From 1849921bee98970f7a70769a4b5018ffca74e162 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 31 Aug 2026 09:57:40 +0200 Subject: [PATCH] Cover turbo libc detection with an E2E test The selector decides between the glibc and the musl turbo build by looking at the filesystem, so it can only be exercised on a real system whose libc is what it is. `phpstan diagnose` already prints the verdict: Turbo platform: linux-gnu-x86_64 (os: Linux, machine: x86_64, libc: gnu, ...) Three legs: - a glibc runner carrying /lib/ld-musl-x86_64.so.1 (what musl-tools or a musl cross-build sysroot leaves behind) must still say linux-gnu-* - Alpine must say linux-musl-* - so must a musl system with no /etc/alpine-release The first one is red: the glob('/lib/ld-musl-*') heuristic sees the loader on disk and selects the musl build, and PHP then refuses to load it at startup with Unable to load dynamic library '.../linux-musl-x86_64/phpstan_turbo-8.5.so' (libc.musl-x86_64.so.1: cannot open shared object file) Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01U8evGx6JricZsa9thKWkou --- .github/workflows/e2e-tests.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index fac692020a3..5ac3e6aea8e 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -886,6 +886,31 @@ jobs: echo "FAIL: tmp was created by a worker, meaning sys_temp_dir='tmp~1' was incorrectly evaluated to 'tmp'" exit 1 fi + - script: | + # A glibc system can carry a musl loader without being a musl system: + # musl-tools, a musl cross-compilation sysroot, or anything else built + # against musl installs /lib/ld-musl-.so.1 as well. PHPStan must + # still pick the glibc turbo build there - picking the musl one makes + # PHP refuse to load the extension at startup: "Unable to load dynamic + # library '.../linux-musl-x86_64/phpstan_turbo-8.5.so' + # (libc.musl-x86_64.so.1: cannot open shared object file)". + sudo touch /lib/ld-musl-x86_64.so.1 + OUTPUT=$(bin/phpstan diagnose -l 0 -c tests/e2e/data/empty.neon) + echo "$OUTPUT" + e2e/bashunit -a contains 'Turbo platform: linux-gnu-' "$OUTPUT" + - script: | + # The mirror image of the leg above: an actual musl system must keep + # picking the musl build - both on Alpine, and (since /etc/alpine-release + # is not what makes a system musl) with that file taken away. The images + # ship no php.ini, so memory_limit would default to 128M, which building + # the DI container already exceeds. + DIAGNOSE='php -d memory_limit=-1 bin/phpstan diagnose -l 0 -c tests/e2e/data/empty.neon' + OUTPUT=$(docker run --rm -v "$PWD:/repo" -w /repo php:8.2-cli-alpine sh -c "$DIAGNOSE") + echo "$OUTPUT" + e2e/bashunit -a contains 'Turbo platform: linux-musl-' "$OUTPUT" + OUTPUT=$(docker run --rm -v "$PWD:/repo" -w /repo php:8.2-cli-alpine sh -c "rm /etc/alpine-release && $DIAGNOSE") + echo "$OUTPUT" + e2e/bashunit -a contains 'Turbo platform: linux-musl-' "$OUTPUT" steps: - name: Harden the runner (Audit all outbound calls)