Skip to content

Commit ab8c3e4

Browse files
committed
add --with-frankenphp-app option to embed an app
1 parent 8d30334 commit ab8c3e4

File tree

5 files changed

+79
-13
lines changed

5 files changed

+79
-13
lines changed

config/env.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ SPC_SKIP_PHP_VERSION_CHECK="no"
4343
; Ignore some check item for bin/spc doctor command, comma separated (e.g. SPC_SKIP_DOCTOR_CHECK_ITEMS="if homebrew has installed")
4444
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
4545
; extra modules that xcaddy will include in the FrankenPHP build
46-
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/frankenphp/caddy --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
46+
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
4747
; The display message for php version output (PHP >= 8.4 available)
4848
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"
4949

config/lib.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"source": "php-src",
88
"lib-depends": [
99
"lib-base",
10-
"micro"
10+
"micro",
11+
"frankenphp"
1112
],
1213
"lib-suggests-linux": [
1314
"libacl",
@@ -940,5 +941,9 @@
940941
"liburing/",
941942
"liburing.h"
942943
]
944+
},
945+
"frankenphp": {
946+
"source": "frankenphp",
947+
"type": "target"
943948
}
944949
}

config/source.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,16 @@
343343
"path": "LICENSE"
344344
}
345345
},
346+
"frankenphp": {
347+
"type": "ghtar",
348+
"repo": "php/frankenphp",
349+
"prefer-stable": true,
350+
"provide-pre-build": false,
351+
"license": {
352+
"type": "file",
353+
"path": "LICENSE"
354+
}
355+
},
346356
"icu-static-win": {
347357
"type": "url",
348358
"url": "https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip",

src/SPC/builder/unix/UnixBuilderBase.php

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
use SPC\store\Config;
1313
use SPC\store\FileSystem;
1414
use SPC\store\pkg\GoXcaddy;
15+
use SPC\store\SourceManager;
1516
use SPC\toolchain\GccNativeToolchain;
1617
use SPC\toolchain\ToolchainManager;
1718
use SPC\util\DependencyUtil;
18-
use SPC\util\GlobalEnvManager;
1919
use SPC\util\SPCConfigUtil;
2020
use SPC\util\SPCTarget;
2121

@@ -134,8 +134,8 @@ protected function sanityCheck(int $build_target): void
134134
if (($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED) {
135135
logger()->info('running embed sanity check');
136136
$sample_file_path = SOURCE_PATH . '/embed-test';
137-
if (!is_dir($sample_file_path)) {
138-
@mkdir($sample_file_path);
137+
if (!is_dir($sample_file_path) && !mkdir($sample_file_path) && !is_dir($sample_file_path)) {
138+
throw new SPCInternalException("Failed to create directory: {$sample_file_path}");
139139
}
140140
// copy embed test files
141141
copy(ROOT_DIR . '/src/globals/common-tests/embed.c', $sample_file_path . '/embed.c');
@@ -264,22 +264,72 @@ protected function patchPhpScripts(): void
264264
}
265265
}
266266

267+
/**
268+
* Process the --with-frankenphp-app option
269+
* Creates app.tar and app.checksum in source/frankenphp directory
270+
*
271+
* @return bool True if the app.tar was created successfully, false otherwise
272+
*/
273+
protected function processFrankenphpApp(): void
274+
{
275+
$frankenphpSourceDir = SOURCE_PATH . '/frankenphp';
276+
SourceManager::initSource(['frankenphp'], ['frankenphp']);
277+
$frankenphpAppPath = $this->getOption('with-frankenphp-app');
278+
279+
if ($frankenphpAppPath) {
280+
if (!is_dir($frankenphpAppPath)) {
281+
throw new WrongUsageException("The path provided to --with-frankenphp-app is not a valid directory: {$frankenphpAppPath}");
282+
}
283+
$appTarPath = $frankenphpSourceDir . '/app.tar';
284+
logger()->info("Creating app.tar from {$frankenphpAppPath}");
285+
286+
shell()->exec('tar -cf ' . escapeshellarg($appTarPath) . ' -C ' . escapeshellarg($frankenphpAppPath) . ' .');
287+
288+
$checksum = hash_file('md5', $appTarPath);
289+
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', $checksum);
290+
} else {
291+
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app.tar');
292+
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app_checksum.txt');
293+
file_put_contents($frankenphpSourceDir . '/app.tar', '');
294+
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', '');
295+
}
296+
}
297+
298+
protected function getFrankenPHPVersion(): string
299+
{
300+
$goModPath = SOURCE_PATH . '/frankenphp/caddy/go.mod';
301+
302+
if (!file_exists($goModPath)) {
303+
throw new SPCInternalException("FrankenPHP caddy/go.mod file not found at {$goModPath}, why did we not download FrankenPHP?");
304+
}
305+
306+
$content = file_get_contents($goModPath);
307+
if (preg_match('/github\.com\/dunglas\/frankenphp\s+v?(\d+\.\d+\.\d+)/', $content, $matches)) {
308+
return $matches[1];
309+
}
310+
311+
throw new SPCInternalException('Could not find FrankenPHP version in caddy/go.mod');
312+
}
313+
267314
protected function buildFrankenphp(): void
268315
{
269-
GlobalEnvManager::addPathIfNotExists(GoXcaddy::getEnvironment()['PATH']);
316+
$this->processFrankenphpApp();
270317
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
271318
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
272319
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
273-
// make it possible to build from a different frankenphp directory!
274-
if (!str_contains($xcaddyModules, '--with github.com/dunglas/frankenphp')) {
275-
$xcaddyModules = '--with github.com/dunglas/frankenphp ' . $xcaddyModules;
276-
}
320+
// Check if we have a custom app.tar in source/frankenphp
321+
$frankenphpSourceDir = SOURCE_PATH . '/frankenphp';
322+
323+
$xcaddyModules = preg_replace('#--with github.com/dunglas/frankenphp(=\S+)?#', '', $xcaddyModules);
324+
$xcaddyModules = preg_replace('#--with github.com/dunglas/frankenphp/caddy(=\S+)?#', '', $xcaddyModules);
325+
$xcaddyModules = "--with github.com/dunglas/frankenphp={$frankenphpSourceDir} " .
326+
"--with github.com/dunglas/frankenphp/caddy={$frankenphpSourceDir}/caddy {$xcaddyModules}";
277327
if ($this->getLib('brotli') === null && str_contains($xcaddyModules, '--with github.com/dunglas/caddy-cbrotli')) {
278328
logger()->warning('caddy-cbrotli module is enabled, but brotli library is not built. Disabling caddy-cbrotli.');
279329
$xcaddyModules = str_replace('--with github.com/dunglas/caddy-cbrotli', '', $xcaddyModules);
280330
}
281-
[, $out] = shell()->execWithResult('go list -m github.com/dunglas/frankenphp@latest');
282-
$frankenPhpVersion = str_replace('github.com/dunglas/frankenphp v', '', $out[0]);
331+
332+
$frankenPhpVersion = $this->getFrankenPHPVersion();
283333
$libphpVersion = $this->getPHPVersion();
284334
$dynamic_exports = '';
285335
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
@@ -317,7 +367,7 @@ protected function buildFrankenphp(): void
317367
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
318368
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' . $debugFlags .
319369
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
320-
"{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
370+
"v{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
321371
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",
322372
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
323373
];

src/SPC/command/BuildPHPCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public function configure(): void
4848
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
4949
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
5050
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
51+
$this->addOption('with-frankenphp-app', null, InputOption::VALUE_REQUIRED, 'Path to a folder to be tarred and included in FrankenPHP build');
5152
}
5253

5354
public function handle(): int

0 commit comments

Comments
 (0)