Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/SPC/builder/BuilderBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public function setLibsOnly(bool $status = true): void
*
* @internal
*/
public function proveExts(array $static_extensions, array $shared_extensions = [], bool $skip_check_deps = false, bool $skip_extract = false): void
public function proveExts(array $static_extensions, array $shared_extensions = [], bool $skip_check_deps = false, bool $skip_extract = false, int $build_target = BUILD_TARGET_NONE): void
{
// judge ext
foreach ($static_extensions as $ext) {
Expand Down Expand Up @@ -171,7 +171,9 @@ public function proveExts(array $static_extensions, array $shared_extensions = [
SourceManager::initSource(exts: [...$static_extensions, ...$shared_extensions]);
$this->emitPatchPoint('after-exts-extract');
// patch micro
SourcePatcher::patchMicro();
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
SourcePatcher::patchMicro();
}
}

foreach ([...$static_extensions, ...$shared_extensions] as $extension) {
Expand Down
16 changes: 0 additions & 16 deletions src/SPC/builder/Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use SPC\toolchain\ZigToolchain;
use SPC\util\GlobalEnvManager;
use SPC\util\SPCConfigUtil;
use SPC\util\SPCTarget;

class Extension
{
Expand Down Expand Up @@ -187,14 +186,6 @@ public function patchBeforeWindowsConfigure(): bool
*/
public function patchBeforeMake(): bool
{
if (SPCTarget::getTargetOS() === 'Linux' && $this->isBuildShared() && ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS'))) {
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/Makefile',
"/^(shared_objects_{$this->getName()}\\s*=.*)$/m",
"$1 {$objs}",
);
return true;
}
return false;
}

Expand Down Expand Up @@ -244,13 +235,6 @@ public function patchBeforeSharedMake(): bool
);
}

if ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS')) {
FileSystem::replaceFileRegex(
$this->source_dir . '/Makefile',
"/^(shared_objects_{$this->getName()}\\s*=.*)$/m",
"$1 {$objs}",
);
}
return true;
}

Expand Down
71 changes: 44 additions & 27 deletions src/SPC/builder/linux/LinuxBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use SPC\toolchain\ToolchainManager;
use SPC\toolchain\ZigToolchain;
use SPC\util\GlobalEnvManager;
use SPC\util\PgoManager;
use SPC\util\SPCConfigUtil;
use SPC\util\SPCTarget;

Expand All @@ -22,6 +23,8 @@ class LinuxBuilder extends UnixBuilderBase
/** @var bool Micro patch phar flag */
private bool $phar_patched = false;

private ?PgoManager $pgo = null;

public function __construct(array $options = [])
{
$this->options = $options;
Expand All @@ -48,6 +51,8 @@ public function __construct(array $options = [])
*/
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
$this->pgo = PgoManager::fromBuilder($this, $build_target);

$cflags = $this->arch_c_flags;
f_putenv('CFLAGS=' . $cflags);

Expand Down Expand Up @@ -129,35 +134,40 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void

$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this);
PgoManager::patchBeforeMake($this);

$this->cleanMake();

if ($enableCli) {
logger()->info('building cli');
$this->buildCli();
}
if ($enableFpm) {
logger()->info('building fpm');
$this->buildFpm();
}
if ($enableCgi) {
logger()->info('building cgi');
$this->buildCgi();
}
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro();
}
if ($enableEmbed) {
logger()->info('building embed');
if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
$pgo = $this->pgo;
$needsClean = false;
$sapiBuilds = [
['cli', $enableCli, true, fn () => $this->buildCli()],
['fpm', $enableFpm, true, fn () => $this->buildFpm()],
['cgi', $enableCgi, true, fn () => $this->buildCgi()],
['micro', $enableMicro, true, fn () => $this->buildMicro()],
['embed', $enableEmbed, true, function () use ($enableMicro): void {
if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
}
$this->buildEmbed();
}],
// frankenphp doesn't rebuild php-src; xcaddy links against the deployed libphp.so
['frankenphp', $enableFrankenphp, false, fn () => $this->buildFrankenphp()],
];

foreach ($sapiBuilds as [$sapi, $enabled, $rebuildsPhpSrc, $build]) {
if (!$enabled) {
continue;
}
$this->buildEmbed();
}
if ($enableFrankenphp) {
logger()->info('building frankenphp');
$this->buildFrankenphp();
if ($pgo) {
if ($needsClean && $rebuildsPhpSrc) {
$this->cleanMake();
}
$pgo->applyForSapi($sapi);
$needsClean = $needsClean || $rebuildsPhpSrc;
}
logger()->info('building ' . $sapi);
$build();
}
$shared_extensions = array_map('trim', array_filter(explode(',', $this->getOption('build-shared'))));
if (!empty($shared_extensions)) {
Expand Down Expand Up @@ -327,11 +337,18 @@ private function getMakeExtraVars(): array
$config = (new SPCConfigUtil($this, ['libs_only_deps' => true, 'absolute_libs' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
$static = SPCTarget::isStatic() ? '-all-static' : '';
$lib = BUILD_LIB_PATH;
$extra_ldflags = (string) getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS');
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared'
&& !str_contains($extra_ldflags, '-avoid-version')
&& !preg_match('/-release\s+\S+/', $extra_ldflags)) {
$extra_ldflags = trim($extra_ldflags . ' -avoid-version -module');
}
$extra_ldflags_program = trim("-L{$lib} {$static} -pie " . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'));
return array_filter([
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
'EXTRA_LIBS' => $config['libs'],
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie",
'EXTRA_LDFLAGS' => $extra_ldflags,
'EXTRA_LDFLAGS_PROGRAM' => $extra_ldflags_program,
]);
}

Expand Down
6 changes: 4 additions & 2 deletions src/SPC/builder/linux/library/icu.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ class icu extends LinuxLibraryBase

protected function build(): void
{
$userCxxFlags = trim((string) getenv('SPC_DEFAULT_CXX_FLAGS'));
$userLdFlags = trim((string) getenv('SPC_DEFAULT_LD_FLAGS'));
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"';
$cxxflags = 'CXXFLAGS="-std=c++17 -DPIC -fPIC -fno-ident"';
$ldflags = SPCTarget::isStatic() ? 'LDFLAGS="-static"' : '';
$cxxflags = "CXXFLAGS=\"-std=c++17 -DPIC -fPIC -fno-ident {$userCxxFlags}\"";
$ldflags = SPCTarget::isStatic() ? "LDFLAGS=\"-static {$userLdFlags}\"" : "LDFLAGS=\"{$userLdFlags}\"";
shell()->cd($this->source_dir . '/source')->initializeEnv($this)
->exec(
"{$cppflags} {$cxxflags} {$ldflags} " .
Expand Down
8 changes: 7 additions & 1 deletion src/SPC/builder/linux/library/openssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public function build(): void
$openssl_dir ??= '/etc/ssl';
$ex_lib = trim($ex_lib);

// OpenSSL's Configure ignores env CFLAGS for its target template; pass our flags as extra args after the target.
$userCFlags = trim((string) getenv('SPC_DEFAULT_C_FLAGS'));
$userLdFlags = trim((string) getenv('SPC_DEFAULT_LD_FLAGS'));
$userExtraFlags = trim($userCFlags . ' ' . $userLdFlags);

shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
"{$env} ./Configure no-shared {$extra} " .
Expand All @@ -67,7 +72,8 @@ public function build(): void
'enable-pie ' .
'no-legacy ' .
'no-tests ' .
"linux-{$arch}"
"linux-{$arch} " .
$userExtraFlags
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
Expand Down
5 changes: 3 additions & 2 deletions src/SPC/builder/unix/UnixBuilderBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public function deployBinary(string $src, string $dst, bool $executable = true):
throw new SPCInternalException("Deploy failed. Cannot find file after copy: {$dst}");
}

if (!$this->getOption('no-strip')) {
if (!$this->getOption('no-strip') && !$this->getOption('pgi') && !$this->getOption('cs-pgi')) {
// extract debug info
$this->extractDebugInfo($dst);
// extra strip
Expand Down Expand Up @@ -450,10 +450,11 @@ protected function buildFrankenphp(): void
$cflags .= ' -Wno-error=missing-profile';
$libs .= ' -lgcov';
}
$extraLdProgram = (string) getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM');
$env = [...[
'CGO_ENABLED' => '1',
'CGO_CFLAGS' => clean_spaces($cflags),
'CGO_LDFLAGS' => "{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs}",
'CGO_LDFLAGS' => trim("{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs} {$extraLdProgram}"),
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' .
'-X \'github.com/caddyserver/caddy/v2/modules/caddyhttp.ServerHeader=FrankenPHP Caddy\' ' .
Expand Down
3 changes: 2 additions & 1 deletion src/SPC/builder/unix/library/bzip2.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ trait bzip2
{
public function patchBeforeBuild(): bool
{
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'CFLAGS=-Wall', 'CFLAGS=-fPIC -Wall');
$extra = trim((string) getenv('SPC_DEFAULT_C_FLAGS'));
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'CFLAGS=-Wall', "CFLAGS=-Wall {$extra}");
return true;
}

Expand Down
8 changes: 5 additions & 3 deletions src/SPC/command/BuildPHPCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public function configure(): void
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
$this->addOption('with-frankenphp-app', null, InputOption::VALUE_REQUIRED, 'Path to a folder to be embedded in FrankenPHP');
$this->addOption('pgi', null, null, 'Build instrumented binaries (-fprofile-generate). Run them to collect .profraw files, then re-run with --pgo.');
$this->addOption('cs-pgi', null, null, 'Build cs-instrumented binaries (-fprofile-use=<existing.profdata> -fcs-profile-generate). Requires a prior --pgi+--pgo cycle.');
$this->addOption('pgo', null, null, 'Build optimised binaries (-fprofile-use) from .profraw collected by a previous --pgi run.');
}

public function handle(): int
Expand Down Expand Up @@ -177,7 +180,7 @@ public function handle(): int
// compile libraries
$builder->proveLibs($libraries);
// check extensions
$builder->proveExts($static_extensions, $shared_extensions);
$builder->proveExts($static_extensions, $shared_extensions, build_target: $rule);
// validate libs and extensions
$builder->validateLibsAndExts();

Expand Down Expand Up @@ -210,9 +213,8 @@ public function handle(): int

// clean old modules that may conflict with the new php build
FileSystem::removeDir(BUILD_MODULES_PATH);
// start to build
$builder->buildPHP($rule);

$builder->buildPHP($rule);
$builder->testPHP($rule);

// compile stopwatch :P
Expand Down
8 changes: 8 additions & 0 deletions src/SPC/command/CraftCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class CraftCommand extends BuildCommand
public function configure(): void
{
$this->addArgument('craft', null, 'Path to craft.yml file', WORKING_DIR . '/craft.yml');
$this->addOption('pgi', null, null, 'Forward --pgi to the inner build (instrumented binaries).');
$this->addOption('cs-pgi', null, null, 'Forward --cs-pgi to the inner build (cs-instrumented binaries).');
$this->addOption('pgo', null, null, 'Forward --pgo to the inner build (use collected profile data).');
}

public function handle(): int
Expand Down Expand Up @@ -105,6 +108,11 @@ public function handle(): int
if ($craft['craft-options']['build']) {
$args = [$static_extensions, "--with-libs={$libs}", "--build-shared={$shared_extensions}", ...array_map(fn ($x) => "--build-{$x}", $craft['sapi'])];
$this->optionsToArguments($craft['build-options'], $args);
foreach (['pgi', 'cs-pgi', 'pgo'] as $pgoFlag) {
if ($this->getOption($pgoFlag)) {
$args[] = "--{$pgoFlag}";
}
}
$retcode = $this->runCommand('build', ...$args);
if ($retcode !== 0) {
$this->output->writeln('<error>craft build failed</error>');
Expand Down
Loading
Loading