From a75ee18599b260b60e782bff7b1517ce170c22a4 Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Wed, 14 May 2025 00:00:26 +0200 Subject: [PATCH 1/2] allow installing an embedded php-cli --- build-static.sh | 21 ++++++++++++-- caddy/frankenphp/main.go | 1 - caddy/php-installer.go | 52 ++++++++++++++++++++++++++++++++++ docs/static.md | 1 + static-builder-gnu.Dockerfile | 3 ++ static-builder-musl.Dockerfile | 2 ++ 6 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 caddy/php-installer.go diff --git a/build-static.sh b/build-static.sh index 685984d63d..8db7e59d5f 100755 --- a/build-static.sh +++ b/build-static.sh @@ -21,6 +21,7 @@ os="$(uname -s | tr '[:upper:]' '[:lower:]')" # - MIMALLOC: Use mimalloc as the allocator if set to 1 (default: none) # - XCADDY_ARGS: Additional arguments to pass to xcaddy # - RELEASE: [maintainer only] Create a GitHub release if set to 1 (default: none) +# - INCLUDE_CLI: embeds the PHP CLI in FrankenPHP and enables a command for extracting it (default: none) # - SPC_REL_TYPE: Release type to download (accept "source" and "binary", default: "source") # - SPC_OPT_BUILD_ARGS: Additional arguments to pass to spc build @@ -201,6 +202,11 @@ if [ -n "${MIMALLOC}" ]; then fi fi +SPC_BUILD_COMMAND="--build-embed" +if [ "${INCLUDE_CLI}" ]; then + SPC_BUILD_COMMAND="--build-embed --build-cli" +fi + # Build libphp if necessary cache_key="${PHP_VERSION}-${PHP_EXTENSIONS}-${PHP_EXTENSION_LIBS}" if [ -f ../cache_key ] && [ "$(cat ../cache_key)" = "${cache_key}" ] && [ -f "buildroot/lib/libphp.a" ]; then @@ -210,11 +216,15 @@ else # shellcheck disable=SC2086 ${spcCommand} download --with-php="${PHP_VERSION}" --for-extensions="${PHP_EXTENSIONS}" --for-libs="${PHP_EXTENSION_LIBS}" ${SPC_OPT_DOWNLOAD_ARGS} # shellcheck disable=SC2086 - ${spcCommand} build --enable-zts --build-embed ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}" + ${spcCommand} build --enable-zts ${SPC_BUILD_COMMAND} ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}" echo -n "${cache_key}" >../cache_key fi +if [ "${INCLUDE_CLI}" ]; then + cp "${PWD}/buildroot/bin/php" ../../caddy/frankenphp/php-cli +fi + if ! type "go" >/dev/null 2>&1; then echo "The \"go\" command must be installed." exit 1 @@ -315,12 +325,17 @@ if [ "${SPC_LIBC}" = "musl" ]; then muslStackSizeFix="-Wl,-z,stack-size=0x80000" fi +INCLUDE_CLI_TAG="" +if [ "${INCLUDE_CLI}" ]; then + INCLUDE_CLI_TAG="include_php_cli," +fi + go env cd caddy/ if [ -z "${SPC_LIBC}" ] || [ "${SPC_LIBC}" = "musl" ]; then - xcaddyGoBuildFlags="-buildmode=pie -tags cgo,netgo,osusergo,static_build,nobadger,nomysql,nopgx -ldflags \"-linkmode=external -extldflags '-static-pie ${muslStackSizeFix}' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'\"" + xcaddyGoBuildFlags="-buildmode=pie -tags cgo,${INCLUDE_CLI_TAG}netgo,osusergo,static_build,nobadger,nomysql,nopgx -ldflags \"-linkmode=external -extldflags '-static-pie ${muslStackSizeFix}' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'\"" elif [ "${SPC_LIBC}" = "glibc" ]; then - xcaddyGoBuildFlags="-buildmode=pie -tags cgo,netgo,osusergo,nobadger,nomysql,nopgx -ldflags \"-linkmode=external -extldflags '-pie' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'\"" + xcaddyGoBuildFlags="-buildmode=pie -tags cgo,${INCLUDE_CLI_TAG}netgo,osusergo,nobadger,nomysql,nopgx -ldflags \"-linkmode=external -extldflags '-pie' ${extraLdflags} -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ${FRANKENPHP_VERSION} PHP ${LIBPHP_VERSION} Caddy'\"" fi # shellcheck disable=SC2086 diff --git a/caddy/frankenphp/main.go b/caddy/frankenphp/main.go index 5b5fc0d7c9..825b1f1bb2 100644 --- a/caddy/frankenphp/main.go +++ b/caddy/frankenphp/main.go @@ -2,7 +2,6 @@ package main import ( caddycmd "github.com/caddyserver/caddy/v2/cmd" - // plug in Caddy modules here. _ "github.com/caddyserver/caddy/v2/modules/standard" _ "github.com/dunglas/caddy-cbrotli" diff --git a/caddy/php-installer.go b/caddy/php-installer.go new file mode 100644 index 0000000000..c97cb8d16b --- /dev/null +++ b/caddy/php-installer.go @@ -0,0 +1,52 @@ +//go:build include_php_cli + +package caddy + +import ( + _ "embed" + "errors" + "fmt" + caddycmd "github.com/caddyserver/caddy/v2/cmd" + "github.com/spf13/cobra" + "os" +) + +//go:embed frankenphp/php-cli +var phpcli []byte + +func init() { + caddycmd.RegisterCommand(caddycmd.Command{ + Name: "install-php", + Usage: "location", + Short: "Installs the embedded PHP binary to the desired location", + Long: ` +FrankenPHP was embedded with a php-cli binary. You can extract this to the desired location.`, + CobraFunc: func(cmd *cobra.Command) { + cmd.DisableFlagParsing = true + cmd.RunE = caddycmd.WrapCommandFuncForCobra(extractPHP) + }, + }) +} + +func extractPHP(fs caddycmd.Flags) (int, error) { + args := os.Args[2:] + if len(args) < 1 { + return 1, errors.New("the location is required") + } + + destPath := args[0] + + err := os.WriteFile(destPath, phpcli, 0777) + if err != nil { + err = fmt.Errorf("Failed to write php-cli to %s: %v\n", destPath, err) + if err != nil { + panic(err) + } + os.Exit(1) + return 1, nil + } + + os.Exit(0) + + return 0, nil +} diff --git a/docs/static.md b/docs/static.md index dd11f36cb0..d88488aff8 100644 --- a/docs/static.md +++ b/docs/static.md @@ -128,6 +128,7 @@ script to customize the static build: - `DEBUG_SYMBOLS`: when set, debug-symbols will not be stripped and will be added to the binary - `MIMALLOC`: (experimental, Linux-only) replace musl's mallocng by [mimalloc](https://github.com/microsoft/mimalloc) for improved performance. We only recommend using this for musl targeting builds, for glibc prefer disabling this option and using [`LD_PRELOAD`](https://microsoft.github.io/mimalloc/overrides.html) when you run your binary instead. - `RELEASE`: (maintainers only) when set, the resulting binary will be uploaded on GitHub +- `INCLUDE_CLI`: embeds the PHP CLI in the resulting binary which can be installed with the `install-php` command ## Extensions diff --git a/static-builder-gnu.Dockerfile b/static-builder-gnu.Dockerfile index 7d6a7391cb..14520beb5d 100644 --- a/static-builder-gnu.Dockerfile +++ b/static-builder-gnu.Dockerfile @@ -11,6 +11,9 @@ ARG BUILD_PACKAGES='' ARG PHP_VERSION='' ENV PHP_VERSION=${PHP_VERSION} +ARG INCLUDE_CLI='' +ENV INCLUDE_CLI=${INCLUDE_CLI} + # args passed to static-php-cli ARG PHP_EXTENSIONS='' ARG PHP_EXTENSION_LIBS='' diff --git a/static-builder-musl.Dockerfile b/static-builder-musl.Dockerfile index 2bea7d8fe9..b17f9d92ba 100644 --- a/static-builder-musl.Dockerfile +++ b/static-builder-musl.Dockerfile @@ -20,6 +20,8 @@ ARG EMBED='' ARG DEBUG_SYMBOLS='' ARG MIMALLOC='' ARG NO_COMPRESS='' +ARG INCLUDE_CLI='' +ENV INCLUDE_CLI=${INCLUDE_CLI} ENV GOTOOLCHAIN=local From cd7775790fbeb3219ec335ae6719e75c6b569eeb Mon Sep 17 00:00:00 2001 From: Robert Landers Date: Sat, 7 Jun 2025 15:30:34 +0200 Subject: [PATCH 2/2] move --build-cli to BUILD_ARGS --- build-static.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/build-static.sh b/build-static.sh index 8db7e59d5f..d8bee0114a 100755 --- a/build-static.sh +++ b/build-static.sh @@ -56,6 +56,10 @@ fi if [ -n "${DEBUG_SYMBOLS}" ]; then SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --no-strip" fi +# build php-cli for embedding it +if [ -n "${INCLUDE_CLI}" ]; then + SPC_OPT_BUILD_ARGS="${SPC_OPT_BUILD_ARGS} --build-cli" +fi # php version to build if [ -z "${PHP_VERSION}" ]; then get_latest_php_version() { @@ -202,11 +206,6 @@ if [ -n "${MIMALLOC}" ]; then fi fi -SPC_BUILD_COMMAND="--build-embed" -if [ "${INCLUDE_CLI}" ]; then - SPC_BUILD_COMMAND="--build-embed --build-cli" -fi - # Build libphp if necessary cache_key="${PHP_VERSION}-${PHP_EXTENSIONS}-${PHP_EXTENSION_LIBS}" if [ -f ../cache_key ] && [ "$(cat ../cache_key)" = "${cache_key}" ] && [ -f "buildroot/lib/libphp.a" ]; then @@ -216,7 +215,7 @@ else # shellcheck disable=SC2086 ${spcCommand} download --with-php="${PHP_VERSION}" --for-extensions="${PHP_EXTENSIONS}" --for-libs="${PHP_EXTENSION_LIBS}" ${SPC_OPT_DOWNLOAD_ARGS} # shellcheck disable=SC2086 - ${spcCommand} build --enable-zts ${SPC_BUILD_COMMAND} ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}" + ${spcCommand} build --enable-zts --build-embed ${SPC_OPT_BUILD_ARGS} "${PHP_EXTENSIONS}" --with-libs="${PHP_EXTENSION_LIBS}" echo -n "${cache_key}" >../cache_key fi