mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 14:25:41 +08:00
Refactor package resolution to filter only available build artifacts
This commit is contained in:
@@ -29,7 +29,6 @@ class nghttp2
|
||||
->build();
|
||||
|
||||
FileSystem::replaceFileStr($lib->getIncludeDir() . '\nghttp2\nghttp2.h', '#ifdef NGHTTP2_STATICLIB', '#if 1');
|
||||
|
||||
}
|
||||
|
||||
#[BuildFor('Linux')]
|
||||
|
||||
@@ -577,7 +577,7 @@ trait unix
|
||||
copy(ROOT_DIR . '/src/globals/common-tests/embed.c', $sample_file_path . '/embed.c');
|
||||
copy(ROOT_DIR . '/src/globals/common-tests/embed.php', $sample_file_path . '/embed.php');
|
||||
|
||||
$config = new SPCConfigUtil()->config(array_map(fn ($x) => $x->getName(), $installer->getResolvedPackages()));
|
||||
$config = new SPCConfigUtil()->config($installer->getAvailableResolvedPackageNames());
|
||||
$lens = "{$config['cflags']} {$config['ldflags']} {$config['libs']}";
|
||||
if ($toolchain->isStatic()) {
|
||||
$lens .= ' -static';
|
||||
@@ -735,7 +735,7 @@ trait unix
|
||||
*/
|
||||
private function makeVars(PackageInstaller $installer): array
|
||||
{
|
||||
$config = new SPCConfigUtil(['libs_only_deps' => true])->config(array_map(fn ($x) => $x->getName(), $installer->getResolvedPackages()));
|
||||
$config = new SPCConfigUtil(['libs_only_deps' => true])->config($installer->getAvailableResolvedPackageNames());
|
||||
$static = ApplicationContext::get(ToolchainInterface::class)->isStatic() ? '-all-static' : '';
|
||||
$pie = SystemTarget::getTargetOS() === 'Linux' ? '-pie' : '';
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ trait windows
|
||||
while ($i < count($lines)) {
|
||||
$line = $lines[$i];
|
||||
// Check if this is the embed lib target dependency line (contains the lib name and $(BUILD_DIR)\$(PHPLIB))
|
||||
if (str_contains($line, "\$(BUILD_DIR)\\{$embed_lib}:") && str_contains($line, '$(BUILD_DIR)\\$(PHPLIB)')) {
|
||||
if (str_contains($line, "\$(BUILD_DIR)\\{$embed_lib}:") && str_contains($line, '$(BUILD_DIR)\$(PHPLIB)')) {
|
||||
// Replace the dependency line
|
||||
// Original: $(BUILD_DIR)\php8embed.lib: $(DEPS_EMBED) $(EMBED_GLOBAL_OBJS) $(BUILD_DIR)\$(PHPLIB) $(BUILD_DIR)\php8embed.lib.res $(BUILD_DIR)\php8embed.lib.manifest
|
||||
// New: $(BUILD_DIR)\php8embed.lib: $(DEPS_EMBED) $(EMBED_GLOBAL_OBJS) $(PHP_GLOBAL_OBJS) $(STATIC_EXT_OBJS) $(ASM_OBJS) $(BUILD_DIR)\php8embed.lib.res $(BUILD_DIR)\php8embed.lib.manifest
|
||||
@@ -347,7 +347,7 @@ trait windows
|
||||
if ($i < count($lines) && str_contains($lines[$i], '$(MAKE_LIB)')) {
|
||||
$cmd_line = $lines[$i];
|
||||
// Remove $(BUILD_DIR)\$(PHPLIB) from the command (note the backslash)
|
||||
$cmd_line = str_replace(' $(BUILD_DIR)\\$(PHPLIB)', '', $cmd_line);
|
||||
$cmd_line = str_replace(' $(BUILD_DIR)\$(PHPLIB)', '', $cmd_line);
|
||||
// Add PHP_GLOBAL_OBJS_RESP and STATIC_EXT_OBJS_RESP after EMBED_GLOBAL_OBJS_RESP
|
||||
$cmd_line = str_replace(
|
||||
'$(EMBED_GLOBAL_OBJS_RESP)',
|
||||
@@ -418,84 +418,6 @@ trait windows
|
||||
$this->installPhpHeadersForWindows($package, $installer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install PHP headers to buildroot/include for embed SAPI development.
|
||||
* This mirrors the 'make install-headers' behavior on Unix.
|
||||
*/
|
||||
private function installPhpHeadersForWindows(TargetPackage $package, PackageInstaller $installer): void
|
||||
{
|
||||
InteractiveTerm::setMessage('Installing PHP headers for embed SAPI');
|
||||
|
||||
$source_dir = $package->getSourceDir();
|
||||
$include_dir = $package->getIncludeDir();
|
||||
$php_include_dir = "{$include_dir}\\php";
|
||||
|
||||
// Create directory structure
|
||||
FileSystem::createDir("{$php_include_dir}\\main");
|
||||
FileSystem::createDir("{$php_include_dir}\\Zend");
|
||||
FileSystem::createDir("{$php_include_dir}\\TSRM");
|
||||
FileSystem::createDir("{$php_include_dir}\\sapi\\embed");
|
||||
|
||||
// Copy main/*.h
|
||||
foreach (glob("{$source_dir}\\main\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$php_include_dir}\\main\\" . basename($h));
|
||||
}
|
||||
|
||||
// Copy Zend/*.h
|
||||
foreach (glob("{$source_dir}\\Zend\\*.h") as $h) {
|
||||
$target = "{$php_include_dir}\\Zend\\" . basename($h);
|
||||
FileSystem::copy($h, $target);
|
||||
// Fix GCC-specific #warning directive not supported by MSVC
|
||||
if (basename($h) === 'zend_atomic.h') {
|
||||
FileSystem::replaceFileStr($target, '#warning No atomics support detected. Please open an issue with platform details.', '#pragma message("No atomics support detected. Please open an issue with platform details.")');
|
||||
}
|
||||
}
|
||||
|
||||
// Copy TSRM/*.h
|
||||
foreach (glob("{$source_dir}\\TSRM\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$php_include_dir}\\TSRM\\" . basename($h));
|
||||
}
|
||||
|
||||
// Copy embed SAPI header
|
||||
FileSystem::copy("{$source_dir}\\sapi\\embed\\php_embed.h", "{$php_include_dir}\\sapi\\embed\\php_embed.h");
|
||||
|
||||
// Copy generated config.h (config.w32.h on Windows) to php_config.h
|
||||
$rel_type = 'Release';
|
||||
$ts = $package->getBuildOption('enable-zts', false) ? '_TS' : '';
|
||||
$build_dir = "{$source_dir}\\x64\\{$rel_type}{$ts}";
|
||||
|
||||
// Always copy config.w32.h from source (it's used for both build and headers)
|
||||
if (file_exists("{$source_dir}\\main\\config.w32.h")) {
|
||||
FileSystem::copy("{$source_dir}\\main\\config.w32.h", "{$php_include_dir}\\main\\php_config.h");
|
||||
}
|
||||
|
||||
// Windows: zend_config.w32.h must be copied as zend_config.h for Zend headers to work
|
||||
if (file_exists("{$source_dir}\\Zend\\zend_config.w32.h")) {
|
||||
FileSystem::copy("{$source_dir}\\Zend\\zend_config.w32.h", "{$php_include_dir}\\Zend\\zend_config.h");
|
||||
}
|
||||
|
||||
// Copy extension headers for enabled extensions
|
||||
foreach ($installer->getResolvedPackages(PhpExtensionPackage::class) as $ext) {
|
||||
$ext_name = $ext->getExtensionName();
|
||||
$ext_dir = "{$source_dir}\\ext\\{$ext_name}";
|
||||
if (is_dir($ext_dir)) {
|
||||
$target_ext_dir = "{$php_include_dir}\\ext\\{$ext_name}";
|
||||
FileSystem::createDir($target_ext_dir);
|
||||
foreach (glob("{$ext_dir}\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$target_ext_dir}\\" . basename($h));
|
||||
}
|
||||
// Also copy any arginfo headers
|
||||
foreach (glob("{$ext_dir}\\*_arginfo.h") as $h) {
|
||||
if (!file_exists("{$target_ext_dir}\\" . basename($h))) {
|
||||
FileSystem::copy($h, "{$target_ext_dir}\\" . basename($h));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$package->setOutput('PHP headers path for embed SAPI', $php_include_dir);
|
||||
}
|
||||
|
||||
#[BuildFor('Windows')]
|
||||
public function buildWin(TargetPackage $package): void
|
||||
{
|
||||
@@ -780,4 +702,82 @@ C_CODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install PHP headers to buildroot/include for embed SAPI development.
|
||||
* This mirrors the 'make install-headers' behavior on Unix.
|
||||
*/
|
||||
private function installPhpHeadersForWindows(TargetPackage $package, PackageInstaller $installer): void
|
||||
{
|
||||
InteractiveTerm::setMessage('Installing PHP headers for embed SAPI');
|
||||
|
||||
$source_dir = $package->getSourceDir();
|
||||
$include_dir = $package->getIncludeDir();
|
||||
$php_include_dir = "{$include_dir}\\php";
|
||||
|
||||
// Create directory structure
|
||||
FileSystem::createDir("{$php_include_dir}\\main");
|
||||
FileSystem::createDir("{$php_include_dir}\\Zend");
|
||||
FileSystem::createDir("{$php_include_dir}\\TSRM");
|
||||
FileSystem::createDir("{$php_include_dir}\\sapi\\embed");
|
||||
|
||||
// Copy main/*.h
|
||||
foreach (glob("{$source_dir}\\main\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$php_include_dir}\\main\\" . basename($h));
|
||||
}
|
||||
|
||||
// Copy Zend/*.h
|
||||
foreach (glob("{$source_dir}\\Zend\\*.h") as $h) {
|
||||
$target = "{$php_include_dir}\\Zend\\" . basename($h);
|
||||
FileSystem::copy($h, $target);
|
||||
// Fix GCC-specific #warning directive not supported by MSVC
|
||||
if (basename($h) === 'zend_atomic.h') {
|
||||
FileSystem::replaceFileStr($target, '#warning No atomics support detected. Please open an issue with platform details.', '#pragma message("No atomics support detected. Please open an issue with platform details.")');
|
||||
}
|
||||
}
|
||||
|
||||
// Copy TSRM/*.h
|
||||
foreach (glob("{$source_dir}\\TSRM\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$php_include_dir}\\TSRM\\" . basename($h));
|
||||
}
|
||||
|
||||
// Copy embed SAPI header
|
||||
FileSystem::copy("{$source_dir}\\sapi\\embed\\php_embed.h", "{$php_include_dir}\\sapi\\embed\\php_embed.h");
|
||||
|
||||
// Copy generated config.h (config.w32.h on Windows) to php_config.h
|
||||
$rel_type = 'Release';
|
||||
$ts = $package->getBuildOption('enable-zts', false) ? '_TS' : '';
|
||||
$build_dir = "{$source_dir}\\x64\\{$rel_type}{$ts}";
|
||||
|
||||
// Always copy config.w32.h from source (it's used for both build and headers)
|
||||
if (file_exists("{$source_dir}\\main\\config.w32.h")) {
|
||||
FileSystem::copy("{$source_dir}\\main\\config.w32.h", "{$php_include_dir}\\main\\php_config.h");
|
||||
}
|
||||
|
||||
// Windows: zend_config.w32.h must be copied as zend_config.h for Zend headers to work
|
||||
if (file_exists("{$source_dir}\\Zend\\zend_config.w32.h")) {
|
||||
FileSystem::copy("{$source_dir}\\Zend\\zend_config.w32.h", "{$php_include_dir}\\Zend\\zend_config.h");
|
||||
}
|
||||
|
||||
// Copy extension headers for enabled extensions
|
||||
foreach ($installer->getResolvedPackages(PhpExtensionPackage::class) as $ext) {
|
||||
$ext_name = $ext->getExtensionName();
|
||||
$ext_dir = "{$source_dir}\\ext\\{$ext_name}";
|
||||
if (is_dir($ext_dir)) {
|
||||
$target_ext_dir = "{$php_include_dir}\\ext\\{$ext_name}";
|
||||
FileSystem::createDir($target_ext_dir);
|
||||
foreach (glob("{$ext_dir}\\*.h") as $h) {
|
||||
FileSystem::copy($h, "{$target_ext_dir}\\" . basename($h));
|
||||
}
|
||||
// Also copy any arginfo headers
|
||||
foreach (glob("{$ext_dir}\\*_arginfo.h") as $h) {
|
||||
if (!file_exists("{$target_ext_dir}\\" . basename($h))) {
|
||||
FileSystem::copy($h, "{$target_ext_dir}\\" . basename($h));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$package->setOutput('PHP headers path for embed SAPI', $php_include_dir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,6 +301,32 @@ class PackageInstaller
|
||||
return isset($this->packages[$package_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resolved package names filtered to only packages whose build artifacts are available.
|
||||
* This excludes library packages that haven't been built/installed yet, which naturally
|
||||
* prevents SPCConfigUtil from checking static-lib files of libraries that come after
|
||||
* the current target in the build order (e.g. 'watcher' for frankenphp isn't built
|
||||
* when 'php' is being compiled).
|
||||
*
|
||||
* @return string[] Available resolved package names
|
||||
*/
|
||||
public function getAvailableResolvedPackageNames(): array
|
||||
{
|
||||
return array_values(array_filter(
|
||||
array_keys($this->packages),
|
||||
function (string $name): bool {
|
||||
$pkg = $this->packages[$name] ?? null;
|
||||
// Exclude library packages whose build artifacts don't exist yet.
|
||||
// Extensions and targets are not filtered — extensions are compiled into PHP
|
||||
// and don't have standalone build artifacts.
|
||||
if ($pkg instanceof LibraryPackage && $pkg->getType() === 'library' && !$pkg->isInstalled()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
public function isPackageInstalled(Package|string $package_name): bool
|
||||
{
|
||||
if (empty($this->packages)) {
|
||||
|
||||
Reference in New Issue
Block a user