feat(build): add full static linking support with bundled SDK

- Add fullStatic property to CompilerBase for --full-static flag
- Register --full-static option in Constants with description
- Implement getFullStaticSdkDir method to resolve SDK path
- Modify getIncludePaths to use SDK headers when full static enabled
- Update getLibraryPaths to use
master
韩天峰 2 days ago
parent 59ef088571
commit d73291e11c
  1. 59
      src/Build/NativeBuildConfigurationTrait.php
  2. 1
      src/CompilerBase.php
  3. 6
      src/Metadata/Constants.php
  4. 10
      src/Translator.php

@ -11,8 +11,45 @@ use TypePhp\Platform\Windows;
trait NativeBuildConfigurationTrait
{
/**
* Resolve the fully-static SDK directory (phpx/full-static/sdk).
*
* Fully-static builds are self-contained: the SDK bundles libphp.a and
* libphpx.a plus every required header, so neither PHP_HOME nor php-config
* is consulted. Returns null when fully-static mode is disabled.
*/
protected function getFullStaticSdkDir(): ?string
{
if (!$this->fullStatic) {
return null;
}
$sdkDir = $this->getPhpxDir() . '/full-static/sdk';
if (!is_dir($sdkDir)) {
$this->error(
'--full-static requires the bundled SDK at phpx/full-static/sdk; not found at: ' . $sdkDir
);
}
return $sdkDir;
}
protected function getIncludePaths(): array
{
$sdkDir = $this->getFullStaticSdkDir();
if ($sdkDir !== null) {
return [
$sdkDir . '/include/phpx',
$sdkDir . '/include',
$sdkDir . '/include/php',
$sdkDir . '/include/php/main',
$sdkDir . '/include/php/Zend',
$sdkDir . '/include/php/TSRM',
$sdkDir . '/include/php/ext',
$sdkDir . '/include/php/ext/date/lib',
$this->getBuildDir() . '/include',
$this->getPhpxDir() . '/src/misc',
];
}
$platform = $this->getPlatform();
$includePaths = [
$this->getPhpxDir() . '/include',
@ -38,6 +75,11 @@ trait NativeBuildConfigurationTrait
protected function getLibraryPaths(): array
{
$sdkDir = $this->getFullStaticSdkDir();
if ($sdkDir !== null) {
return [$sdkDir . '/lib'];
}
$platform = $this->getPlatform();
$libraryPaths = [
$this->getPhpxDir() . '/lib',
@ -61,6 +103,17 @@ trait NativeBuildConfigurationTrait
*/
protected function getLibraries(): array
{
$sdkDir = $this->getFullStaticSdkDir();
if ($sdkDir !== null) {
// Fully-static: both archives are self-contained. libphpx.a comes
// first because it references symbols resolved by libphp.a; no
// -lgmp/-lgmpxx/-lmpfr or system libc is needed.
return [
$sdkDir . '/lib/libphpx.a',
$sdkDir . '/lib/libphp.a',
];
}
$platform = $this->getPlatform();
$libraries = [];
@ -126,6 +179,12 @@ trait NativeBuildConfigurationTrait
*/
protected function findPhpxLibrary(): ?string
{
$sdkDir = $this->getFullStaticSdkDir();
if ($sdkDir !== null) {
$phpxStaticPath = $sdkDir . '/lib/libphpx.a';
return is_file($phpxStaticPath) ? $phpxStaticPath : null;
}
$platform = $this->getPlatform();
if ($platform instanceof Windows) {

@ -413,6 +413,7 @@ class CompilerBase implements PropertyAccessContext
protected array $userIncludePaths = []; // --include-path / -I: user-provided C++ include dirs
protected array $userDefines = []; // --define / -D: user-provided preprocessor macros
protected bool $enableLto = false; // --lto: enable Link Time Optimization (-flto)
protected bool $fullStatic = false; // --full-static: link against the bundled fully-static SDK
protected string $file;
protected string $dir;

@ -302,6 +302,12 @@ class Constants
'required' => false,
'multiple' => true,
],
'full-static' => [
'longPrefix' => 'full-static',
'description' => 'Enable fully-static linking using the bundled SDK (phpx/full-static/sdk)',
'required' => false,
'noValue' => true,
],
];
/**

@ -218,6 +218,16 @@ class Translator extends Preprocessor
? $this->platform->getDefaultCompiler()
: CompilerFactory::detectCompilerName($this->platform);
// --full-static: the bundled libphp.a/libphpx.a are built by clang.
// gcc and clang compute TLS offsets differently (gcc's layout differs
// by 64 bytes here), which corrupts thread-local variables at runtime,
// so fully-static builds must use a real Linux clang (PHPX_CC/CXX take
// precedence; otherwise fall back to clang) to keep the toolchain consistent.
if ($this->climate->arguments->defined('full-static')) {
$this->fullStatic = true;
$this->cppCompiler = getenv('PHPX_CC') ?: (getenv('CXX') ?: 'clang');
}
if ($this->platform instanceof Windows) {
$libInfo = $this->platform->detectPhpLibs($this->getPhpDir());
$this->windowsPhpEmbedLib = $libInfo['embed'];

Loading…
Cancel
Save