Skip to content
Merged
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
43 changes: 42 additions & 1 deletion bin/spc-alpine-docker
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,47 @@ if [ ! -z "$GITHUB_TOKEN" ]; then
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
fi

# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
FRANKENPHP_APP_PATH=""
NEW_ARGS=()
while [ $# -gt 0 ]; do
case "$1" in
--with-frankenphp-app=*)
FRANKENPHP_APP_PATH="${1#*=}"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift
;;
--with-frankenphp-app)
if [ -n "${2:-}" ]; then
FRANKENPHP_APP_PATH="$2"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift 2
else
NEW_ARGS+=("$1")
shift
fi
;;
*)
NEW_ARGS+=("$1")
shift
;;
esac
done

# Normalize the path and add mount if provided
if [ -n "$FRANKENPHP_APP_PATH" ]; then
# expand ~ to $HOME
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
fi
# make absolute if relative
case "$FRANKENPHP_APP_PATH" in
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
esac
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
fi

# Run docker
# shellcheck disable=SC2068
# shellcheck disable=SC2086
Expand All @@ -183,5 +224,5 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
set -ex
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
else
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc $@
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
fi
43 changes: 42 additions & 1 deletion bin/spc-gnu-docker
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,47 @@ if [ ! -z "$GITHUB_TOKEN" ]; then
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
fi

# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
FRANKENPHP_APP_PATH=""
NEW_ARGS=()
while [ $# -gt 0 ]; do
case "$1" in
--with-frankenphp-app=*)
FRANKENPHP_APP_PATH="${1#*=}"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift
;;
--with-frankenphp-app)
if [ -n "${2:-}" ]; then
FRANKENPHP_APP_PATH="$2"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift 2
else
NEW_ARGS+=("$1")
shift
fi
;;
*)
NEW_ARGS+=("$1")
shift
;;
esac
done

# Normalize the path and add mount if provided
if [ -n "$FRANKENPHP_APP_PATH" ]; then
# expand ~ to $HOME
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
fi
# make absolute if relative
case "$FRANKENPHP_APP_PATH" in
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
esac
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
fi

# Run docker
# shellcheck disable=SC2068
# shellcheck disable=SC2086
Expand All @@ -196,5 +237,5 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
set -ex
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
else
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc $@
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
fi
2 changes: 1 addition & 1 deletion config/env.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ SPC_SKIP_PHP_VERSION_CHECK="no"
; Ignore some check item for bin/spc doctor command, comma separated (e.g. SPC_SKIP_DOCTOR_CHECK_ITEMS="if homebrew has installed")
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
; extra modules that xcaddy will include in the FrankenPHP build
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"
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
; The display message for php version output (PHP >= 8.4 available)
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"

Expand Down
22 changes: 21 additions & 1 deletion config/lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"source": "php-src",
"lib-depends": [
"lib-base",
"micro"
"micro",
"frankenphp"
],
"lib-depends-macos": [
"lib-base",
Expand Down Expand Up @@ -968,5 +969,24 @@
"zstd.h",
"zstd_errors.h"
]
},
"liburing": {
"source": "liburing",
"pkg-configs": [
"liburing",
"liburing-ffi"
],
"static-libs-linux": [
"liburing.a",
"liburing-ffi.a"
],
"headers-linux": [
"liburing/",
"liburing.h"
]
},
"frankenphp": {
"source": "frankenphp",
"type": "target"
}
}
16 changes: 13 additions & 3 deletions config/source.json
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@
}
},
"freetype": {
"type": "git",
"rev": "VER-2-13-2",
"url": "https://github.com/freetype/freetype",
"type": "ghtagtar",
"repo": "freetype/freetype",
"match": "VER-2-\\d+-\\d+",
"license": {
"type": "file",
"path": "LICENSE.TXT"
Expand Down Expand Up @@ -363,6 +363,16 @@
"path": "LICENSE"
}
},
"frankenphp": {
"type": "ghtar",
"repo": "php/frankenphp",
"prefer-stable": true,
"provide-pre-build": false,
"license": {
"type": "file",
"path": "LICENSE"
}
},
"icu-static-win": {
"type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip",
Expand Down
62 changes: 55 additions & 7 deletions src/SPC/builder/unix/UnixBuilderBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\store\pkg\GoXcaddy;
use SPC\store\SourceManager;
use SPC\toolchain\GccNativeToolchain;
use SPC\toolchain\ToolchainManager;
use SPC\util\DependencyUtil;
Expand Down Expand Up @@ -265,22 +266,69 @@ protected function patchPhpScripts(): void
}
}

/**
* Process the --with-frankenphp-app option
* Creates app.tar and app.checksum in source/frankenphp directory
*/
protected function processFrankenphpApp(): void
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about processing frankenphp app before building everything? Although I don't have any build requirements for frankenphp embed app, but if something goes wrong here, it would be annoying to wait for dozens of minutes to build and then report an error.

{
$frankenphpSourceDir = SOURCE_PATH . '/frankenphp';
SourceManager::initSource(['frankenphp'], ['frankenphp']);
$frankenphpAppPath = $this->getOption('with-frankenphp-app');

if ($frankenphpAppPath) {
if (!is_dir($frankenphpAppPath)) {
throw new WrongUsageException("The path provided to --with-frankenphp-app is not a valid directory: {$frankenphpAppPath}");
}
$appTarPath = $frankenphpSourceDir . '/app.tar';
logger()->info("Creating app.tar from {$frankenphpAppPath}");

shell()->exec('tar -cf ' . escapeshellarg($appTarPath) . ' -C ' . escapeshellarg($frankenphpAppPath) . ' .');

$checksum = hash_file('md5', $appTarPath);
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', $checksum);
} else {
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app.tar');
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app_checksum.txt');
file_put_contents($frankenphpSourceDir . '/app.tar', '');
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', '');
}
}

protected function getFrankenPHPVersion(): string
{
$goModPath = SOURCE_PATH . '/frankenphp/caddy/go.mod';

if (!file_exists($goModPath)) {
throw new SPCInternalException("FrankenPHP caddy/go.mod file not found at {$goModPath}, why did we not download FrankenPHP?");
}

$content = file_get_contents($goModPath);
if (preg_match('/github\.com\/dunglas\/frankenphp\s+v?(\d+\.\d+\.\d+)/', $content, $matches)) {
return $matches[1];
}

throw new SPCInternalException('Could not find FrankenPHP version in caddy/go.mod');
}

protected function buildFrankenphp(): void
{
GlobalEnvManager::addPathIfNotExists(GoXcaddy::getPath());
$this->processFrankenphpApp();
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
// make it possible to build from a different frankenphp directory!
if (!str_contains($xcaddyModules, '--with github.com/dunglas/frankenphp')) {
$xcaddyModules = '--with github.com/dunglas/frankenphp ' . $xcaddyModules;
}
$frankenphpSourceDir = SOURCE_PATH . '/frankenphp';

$xcaddyModules = preg_replace('#--with github.com/dunglas/frankenphp\S*#', '', $xcaddyModules);
$xcaddyModules = "--with github.com/dunglas/frankenphp={$frankenphpSourceDir} " .
"--with github.com/dunglas/frankenphp/caddy={$frankenphpSourceDir}/caddy {$xcaddyModules}";
if ($this->getLib('brotli') === null && str_contains($xcaddyModules, '--with github.com/dunglas/caddy-cbrotli')) {
logger()->warning('caddy-cbrotli module is enabled, but brotli library is not built. Disabling caddy-cbrotli.');
$xcaddyModules = str_replace('--with github.com/dunglas/caddy-cbrotli', '', $xcaddyModules);
}
[, $out] = shell()->execWithResult('go list -m github.com/dunglas/frankenphp@latest');
$frankenPhpVersion = str_replace('github.com/dunglas/frankenphp v', '', $out[0]);

$frankenPhpVersion = $this->getFrankenPHPVersion();
$libphpVersion = $this->getPHPVersion();
$dynamic_exports = '';
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
Expand All @@ -290,7 +338,7 @@ protected function buildFrankenphp(): void
$dynamic_exports = ' ' . $dynamicSymbolsArgument;
}
}
$debugFlags = $this->getOption('no-strip') ? '-w -s ' : '';
$debugFlags = $this->getOption('no-strip') ? '' : '-w -s ';
$extLdFlags = "-extldflags '-pie{$dynamic_exports} {$this->arch_ld_flags}'";
$muslTags = '';
$staticFlags = '';
Expand Down
1 change: 1 addition & 0 deletions src/SPC/command/BuildPHPCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public function configure(): void
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
$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');
}

public function handle(): int
Expand Down
2 changes: 1 addition & 1 deletion src/SPC/store/source/PhpSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function fetch(bool $force = false, ?array $config = null, int $lock_as =
{
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
if ($major === '8.5') {
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~daniels/php-8.5.0RC3.tar.xz'], $force);
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~edorian/php-8.5.0RC4.tar.xz'], $force);
} elseif ($major === 'git') {
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
} else {
Expand Down