Repository navigation
BUG : Compiling opcache extensions statically into ZTS PHP , JIT bug #15074
Copy link
Copy link
Closed
Description
Compile target : Statically compiled PHP enable Zend Thread Safe and opcache extension
environment :
OS: alpine
OS-Version: 3.19
CPU ARCH : x86_64
The following code:
docker run --rm -ti --init -w /work alpine:3.18
apk update
apk add vim alpine-sdk xz autoconf automake linux-headers clang-dev clang lld libtool cmake bison re2c gettext coreutils
apk add bash p7zip zip unzip flex pkgconf ca-certificates
apk add wget git curl
apk add vim
vi build-static-php.sh
#!/usr/bin/env bash
__DIR__=$(cd "$(dirname "$0")"; pwd)
set -uex
PHP_VERSION=8.2.21
test -f php-${PHP_VERSION}.tar.gz || curl -fSLo php-${PHP_VERSION}.tar.gz https://github.com/php/php-src/archive/refs/tags/php-${PHP_VERSION}.tar.gz
test -d php-src && rm -rf php-src
mkdir -p php-src
tar --strip-components=1 -C php-src -xf php-${PHP_VERSION}.tar.gz
export CC=clang
export CXX=clang++
export LD=ld.lld
cd php-src
bash ${__DIR__}/opcache-static-compile-patch.sh
./buildconf --force
./configure \
--disable-all \
--disable-cgi \
--enable-shared=no \
--enable-static=yes \
--enable-cli \
--enable-zts \
--disable-phpdbg \
--without-valgrind \
--enable-opcache
sed -i.backup 's/-export-dynamic/-all-static/g' Makefile
make -j $(nproc)
file sapi/cli/php
readelf -h sapi/cli/php
sapi/cli/php -m
sapi/cli/php -v
vi opcache-static-compile-patch.sh
#!/usr/bin/env bash
if [ ! -f ext/opcache/config.m4 ] ; then
echo 'php extension opcache folder no found '
exit 3
fi
cat > ext/opcache/php_opcache.h <<PHP_OPCACHE_H_EOF
#include "php.h"
extern zend_module_entry opcache_module_entry;
#define phpext_opcache_ptr &opcache_module_entry
PHP_OPCACHE_H_EOF
sed -i.backup 's/ext_shared=yes/ext_shared=no/g' ext/opcache/config.m4
sed -i.backup 's/shared,,/\$ext_shared,,/g' ext/opcache/config.m4
sed -i.backup 's/\/\* start Zend extensions \*\//\/\* start Zend extensions \*\/\n#ifdef PHP_ENABLE_OPCACHE\n\textern zend_extension zend_extension_entry;\n\tzend_register_extension(\&zend_extension_entry, NULL);\n#endif/g' main/main.c
cat >> sapi/cli/php_cli.c <<PHP_CLI_OPCACHE_EOF
zend_module_entry opcache_module_entry = {
STANDARD_MODULE_HEADER_EX,
NULL,
NULL,
"opcache",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
PHP_VERSION,
STANDARD_MODULE_PROPERTIES
};
PHP_CLI_OPCACHE_EOF
test -f main/main.c.backup && rm -f main/main.c.backup
test -f ext/opcache/config.m4.backup && rm -f ext/opcache/config.m4.backup
Compile PHP into Static Binary
bash build-static-php.sh
Resulted in this output:
/usr/bin/ld: ext/opcache/jit/zend_jit.o: TLS transition from R_X86_64_TLSGD to R_X86_64_GOTTPOFF against `_tsrm_ls_cache' at 0x12c9a in section `.text' failed
/usr/bin/ld: failed to set dynamic section sizes: bad value
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:261: sapi/cli/php] Error 1
PHP Version
8.2.21
Operating System
alpine 3.18
Reactions are currently unavailable

Activity
jingjingxyk commentedon Jul 23, 2024
script source code : jingjingxyk/swoole-cli@9215808
https://github.com/jingjingxyk/swoole-cli/tree/build_native_php/sapi/tools
https://github.com/swoole/build-static-php/tree/main/sapi/tools
cmb69 commentedon Jul 23, 2024
Well, there might be reason why "OPcache can only be compiled as a shared extension" according to the documentation.
Anyhow, did that work with previous versions of PHP 8.2?
jingjingxyk commentedon Jul 23, 2024
Test PHP version list
PHP_VERSION=8.2.21
PHP_VERSION=8.3.9
PHP_VERSION=8.1.29
PHP_VERSION=8.0.30
They have similar compilation errors
cmb69 commentedon Jul 23, 2024
Thank you! So this is actually a feature request (to be able to compile OPcache statically), but not a report about a regression.
jingjingxyk commentedon Jul 23, 2024
If PHP does not enable ZTS, opcache extension static compilation can be successfully compiled
https://github.com/jingjingxyk/swoole-cli/actions/runs/10062434474/
arnaud-lb commentedon Jul 23, 2024
The problem seems to be that
ldis trying to optimize the relocation here, but fails because we (purposefully) don't generate the exact code thatldis expecting.This does not affect glibc builds, as in this case we use a different relocation in
tsrm_get_ls_cache_tcb_offset(). I believe that it would be safe to do the same for other libcs only when php is being compiled as executable, which we don't know until linking.Fix linker failure when building Opcache statically
arnaud-lb commentedon Jul 26, 2025
Should be fixed by #18939