dunglas/frankenphp

Cannot rebuild static binary

SosthenG opened this issue · 11 comments

What happened?

I can't rebuild a static binary. I managed to get it work a few months ago but now when I try to rebuild (to add an extension I forgot before), I get an error then a binary which is the same as before. To be sure I tried to change the PHP_VERSION from 8.3 to 8.2 but when I check the version of the generated binary it still 8.3.

Using docker buildx:

docker buildx bake \
  --load \
  --set static-builder.args.PHP_EXTENSIONS=pdo_mysql,mysqli,gd,intl,zip,opcache,sockets,pcntl,redis,ssh2,amqp,imap,apcu,igbinary \
  --set static-builder.args.PHP_EXTENSION_LIBS=librabbitmq \
  --set static-builder.args.PHP_VERSION=8.2 \
  static-builder
docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder

Output:

docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder
[+] Building 0.0s (1/1) FINISHED                                                                                                                                                                                 docker:default
 => [internal] load local bake definitions                                                                                                                                                                                 0.0s
ERROR: couldn't find a bake definition
Successfully copied 46.1MB to /home/www/frankenphp
static-builder

When running in a folder with the "docker-bake.hcl" file:

[+] Building 0.1s (1/1) FINISHED                                                                                                                                                                                 docker:default
 => [internal] load local bake definitions                                                                                                                                                                                 0.0s
 => => reading docker-bake.hcl 4.96kB / 4.96kB                                                                                                                                                                             0.0s
ERROR: docker exporter does not currently support exporting manifest lists
Successfully copied 46.1MB to /home/sosthen/dev/frankenphp/frankenphp
static-builder

In both cases, I do get a frankenphp binary but it's the exact same as the one I built a few months ago, version is still 8.3 and I don't have the amqp extension (the one I added since).

Running ./build-static.sh does not work either with the following output:

[11:30:43] [NOTI] Running dangerous command: rm -rf /home/sosthen/dev/frankenphp/dist/static-php-cli/source/php-src/sapi/micro
[11:30:43] [ERRO] Uncaught SPC\exception\FileSystemException: Cannot extract source micro: Command run failed with code[1]: cd /home/sosthen/dev/frankenphp/dist/static-php-cli/source/php-src && cat sapi/micro/patches/static_opcache_81.patch | patch -p1  at /home/sosthen/dev/frankenphp/dist/static-php-cli/src/SPC/store/FileSystem.php(205)
[11:30:43] [ERRO] #0 /home/sosthen/dev/frankenphp/dist/static-php-cli/src/SPC/store/SourceManager.php(65): SPC\store\FileSystem::extractSource()
#1 /home/sosthen/dev/frankenphp/dist/static-php-cli/src/SPC/builder/BuilderBase.php(174): SPC\store\SourceManager::initSource()
#2 /home/sosthen/dev/frankenphp/dist/static-php-cli/src/SPC/command/BuildCliCommand.php(147): SPC\builder\BuilderBase->proveExts()
#3 /home/sosthen/dev/frankenphp/dist/static-php-cli/src/SPC/command/BaseCommand.php(101): SPC\command\BuildCliCommand->handle()
#4 /home/sosthen/dev/frankenphp/dist/static-php-cli/vendor/symfony/console/Command/Command.php(326): SPC\command\BaseCommand->execute()
#5 /home/sosthen/dev/frankenphp/dist/static-php-cli/vendor/symfony/console/Application.php(1078): Symfony\Component\Console\Command\Command->run()
#6 /home/sosthen/dev/frankenphp/dist/static-php-cli/vendor/symfony/console/Application.php(324): Symfony\Component\Console\Application->doRunCommand()
#7 /home/sosthen/dev/frankenphp/dist/static-php-cli/vendor/symfony/console/Application.php(175): Symfony\Component\Console\Application->doRun()
#8 /home/sosthen/dev/frankenphp/dist/static-php-cli/bin/spc(21): Symfony\Component\Console\Application->run()
#9 {main}

Right now I can't find a way to rebuild a static binary nothing seems to work.
Might be related to #704 however this issue is older than my first build which worked so I'm no sure.

Build Type

Official static build

Worker Mode

No

Operating System

GNU/Linux

CPU Architecture

x86_64

PHP configuration

Not the expected one

Relevant log output

No response

You need to download the sources (or clone the Git repo) and run the commands inside the directory containing the full source.
Is it what you're doing?

I tried both inside the source directory and outside, in both cases I get the same binary as always no matter the config (php version or extensions).

I tried recloning from scratch but same error as before and I get the same binary in 8.3 without amqp instead of 8.2 with amqp:

git clone https://github.com/dunglas/frankenphp
Clonage dans 'frankenphp'...
remote: Enumerating objects: 3248, done.
remote: Counting objects: 100% (1256/1256), done.
remote: Compressing objects: 100% (405/405), done.
remote: Total 3248 (delta 1063), reused 905 (delta 851), pack-reused 1992 (from 1)
Réception d'objets: 100% (3248/3248), 3.36 Mio | 21.80 Mio/s, fait.
Résolution des deltas: 100% (2100/2100), fait.
> cd frankenphp
> docker buildx bake \
  --load \
  --set static-builder.args.PHP_EXTENSIONS=pdo_mysql,mysqli,gd,intl,zip,opcache,sockets,pcntl,redis,ssh2,amqp,imap,apcu,igbinary \
  --set static-builder.args.PHP_EXTENSION_LIBS=librabbitmq \
  --set static-builder.args.PHP_VERSION=8.2 \
  static-builder
docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp ; docker rm static-builder
[+] Building 0.1s (1/1) FINISHED                                 docker:default
 => [internal] load local bake definitions                                 0.0s
 => => reading docker-bake.hcl 4.96kB / 4.96kB                             0.0s
ERROR: docker exporter does not currently support exporting manifest lists
Successfully copied 46.1MB to /home/sosthen/dev/frankenphp/frankenphp
static-builder

There is clearly a cached binary that is always copied, I don't know how to force delete it (but anyway it should be replaced if the build worked?)

Can you try to add --set '*.platform=linux/amd64' to the args (or the platform you want to build)?
It looks like your Docker install doesn't have support for multiplatform builds (maybe qemu is missing), but anyway, it's likely not what you want.

Hi,
With the --set '*.platform=linux/amd64' option, I can clearly see that its building something, but then I get the same error I got when trying to manually build (with the macOS instructions, but I'm on PopOS-Ubuntu):

34.46 [08:18:25] [INFO] Build OS:        Linux (x86_64)
34.46 [08:18:25] [INFO] Build SAPI:      embed
34.46 [08:18:25] [INFO] Extensions (17): pdo,mysqlnd,pdo_mysql,mysqli,zlib,gd,intl,zip,opcache,sockets,pcntl,apcu,igbinary,redis,ssh2,amqp,imap
34.46 [08:18:25] [INFO] Libraries (16):  zlib,libpng,libavif,libwebp,libjpeg,bzip2,brotli,freetype,icu,openssl,libzip,liblz4,libssh2,librabbitmq,imap,nghttp2
34.46 [08:18:25] [INFO] Strip Binaries:  yes
34.46 [08:18:25] [INFO] Enable ZTS:      yes
34.46 [08:18:25] [INFO] Opcache JIT:     disabled
34.46 [08:18:25] [INFO] PHP Version:     8.2.23
34.46 [08:18:25] [INFO] Extra Exts (3):  pdo, mysqlnd, zlib
34.46 [08:18:25] [NOTI] Build will start after 2s ...
36.46 [08:18:27] [DEBU] scanning directory /go/src/app/dist/static-php-cli/src/SPC/builder/linux/library
36.47 [08:18:27] [DEBU] enabling libzip without xz
36.47 [08:18:27] [DEBU] enabling libzip without zstd
36.47 [08:18:27] [DEBU] enabling nghttp2 without libxml2
36.47 [08:18:27] [DEBU] scanning directory /go/src/app/dist/static-php-cli/src/SPC/builder/extension
36.47 [08:18:27] [DEBU] Extracting source [php-src] to /go/src/app/dist/static-php-cli/source/php-src ...
36.47 [08:18:27] [INFO] extracting php-src source to /go/src/app/dist/static-php-cli/source/php-src ...
36.47 [08:18:27] [DEBU] Making new directory recursive: /go/src/app/dist/static-php-cli/source/php-src
36.47 [08:18:27] [DEBU] [PASSTHRU] tar -xf /go/src/app/dist/static-php-cli/downloads/php-8.2.23.tar.xz -C /go/src/app/dist/static-php-cli/source/php-src --strip-components 1
37.60 [08:18:28] [INFO] Patched source [php-src] after extracted
37.60 [08:18:28] [DEBU] Extracting source [micro] to /go/src/app/dist/static-php-cli/source/php-src/sapi/micro ...
37.60 [08:18:28] [INFO] extracting micro source to /go/src/app/dist/static-php-cli/source/php-src/sapi/micro ...
37.60 [08:18:28] [DEBU] [PASSTHRU] cp -r "/go/src/app/dist/static-php-cli/downloads/micro" "/go/src/app/dist/static-php-cli/source/php-src/sapi/micro"
37.61 [08:18:28] [INFO] Patching micro with sapi/micro/patches/static_opcache_81.patch
37.61 [08:18:28] [DEBU] [PASSTHRU] cd /go/src/app/dist/static-php-cli/source/php-src && cat sapi/micro/patches/static_opcache_81.patch | patch -p1 
37.61 patching file build/order_by_dep.awk
37.61 patching file ext/opcache/ZendAccelerator.c
37.61 Hunk #1 succeeded at 93 (offset 2 lines).
37.61 Hunk #2 succeeded at 4795 (offset -16 lines).
37.61 patching file ext/opcache/config.m4
37.61 Hunk #2 FAILED at 328.
37.61 1 out of 2 hunks FAILED -- saving rejects to file ext/opcache/config.m4.rej
37.61 patching file ext/opcache/config.w32
37.61 patching file main/main.c
37.61 Hunk #1 succeeded at 2048 with fuzz 2 (offset 37 lines).
37.61 Hunk #2 succeeded at 2305 (offset 40 lines).
37.61 patching file win32/build/confutils.js
37.61 Hunk #1 succeeded at 1534 (offset -1 lines).
37.62 [08:18:28] [NOTI] Running dangerous command: rm -rf /go/src/app/dist/static-php-cli/source/php-src/sapi/micro
37.62 [08:18:28] [ERRO] Uncaught SPC\exception\FileSystemException: Cannot extract source micro: Command run failed with code[1]: cd /go/src/app/dist/static-php-cli/source/php-src && cat sapi/micro/patches/static_opcache_81.patch | patch -p1  at /go/src/app/dist/static-php-cli/src/SPC/store/FileSystem.php(205)
37.62 [08:18:28] [ERRO] #0 /go/src/app/dist/static-php-cli/src/SPC/store/SourceManager.php(65): SPC\store\FileSystem::extractSource()
37.62 #1 /go/src/app/dist/static-php-cli/src/SPC/builder/BuilderBase.php(174): SPC\store\SourceManager::initSource()
37.62 #2 /go/src/app/dist/static-php-cli/src/SPC/command/BuildCliCommand.php(147): SPC\builder\BuilderBase->proveExts()
37.62 #3 /go/src/app/dist/static-php-cli/src/SPC/command/BaseCommand.php(101): SPC\command\BuildCliCommand->handle()
37.62 #4 /go/src/app/dist/static-php-cli/vendor/symfony/console/Command/Command.php(326): SPC\command\BaseCommand->execute()
37.62 #5 /go/src/app/dist/static-php-cli/vendor/symfony/console/Application.php(1078): Symfony\Component\Console\Command\Command->run()
37.62 #6 /go/src/app/dist/static-php-cli/vendor/symfony/console/Application.php(324): Symfony\Component\Console\Application->doRunCommand()
37.62 #7 /go/src/app/dist/static-php-cli/vendor/symfony/console/Application.php(175): Symfony\Component\Console\Application->doRun()
37.62 #8 /go/src/app/dist/static-php-cli/bin/spc(21): Symfony\Component\Console\Application->run()
37.62 #9 {main}
------
static-builder.Dockerfile:107
--------------------
 106 |     
 107 | >>> RUN --mount=type=secret,id=github-token GITHUB_TOKEN=$(cat /run/secrets/github-token) ./build-static.sh && \
 108 | >>> 	rm -Rf dist/static-php-cli/source/*
 109 |     
--------------------
ERROR: failed to solve: process "/bin/ash -eo pipefail -c GITHUB_TOKEN=$(cat /run/secrets/github-token) ./build-static.sh && \trm -Rf dist/static-php-cli/source/*" did not complete successfully: exit code: 1

It's weird that we don't get the same issue in the CI.

@crazywhalecc, by chance, do you have an idea of what's going on? Thanks!

@crazywhalecc I think why opcache isn't enabled when succesfully building with your changed patch has something to do with the HAVE_JIT here, but i'm not entirely sure.

We're compiling without jit enabled, right @dunglas ?

php/php-src@php-8.3.10...php-8.3.11#diff-110981c15bb56fcc439ffddc156b0a03fa516951bdfa479865aaeabbfa9553ef

@psychorama I just tried to rebuild PHP using the --disable-opcache-jit option, but the sanity check still fails. So I guess it's not related to JIT

Actually... our CI is red for the exact same reason: https://github.com/dunglas/frankenphp/actions/runs/10674487251/job/29585077831#step:5:1

I'll try to take a look tomorrow.

Maybe could we downgrade PHP in the meantime?

It works fine in the latest release!

Please note that I do have to add the --set '*.platform=linux/amd64' for it to work, maybe this should be added to the documentation?