次は PHP 8.1 へ(1)
PHP 8.0 のサポート期限は2023年11月26日までの予定
PHP 8.0系への移行が完了したばかりですが、PHP 8.0系列のサポート期限は今年の11月26日で切れてしまいます。
PHP 8.0への移行が難航した教訓から、できるだけ早めに PHP 8.1へ移行しておきたいと思い試行を始めたのだけど、やってみたらコチラも色々と大変でした。
まだ PHP 8.1 の単体テストができるようになった段階であり、PHPスクリプトの互換性チェック、修正、動作確認等はこれからなのだけど、現時点の状態を記しておこうと思います。
1. PHP 8.1用のビルドスクリプト
何度もトライ&エラーを繰り返して何度もビルドすることになるので、今回もビルド用をスクリプトを作っておきます。
#!/usr/local/bin/bash -x
export MACOSX_DEPLOYMENT_TARGET=10.4
export GCC="/usr/local"
export SSL="/usr/local/libressl"
export PATH="${GCC}/bin:/usr/local/bin:/usr/bin:${PATH}"
export DYLD_LIBRARY_PATH="${SSL}/lib:${GCC}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH="${SSL}/lib/pkgconfig:${PKG_CONFIG_PATH}"
export OPTFLAGS="-O2 -mpowerpc -mcpu=7450 -maltivec"
export CFLAGS="${OPTFLAGS} -mmacosx-version-min=${MACOSX_DEPLOYMENT_TARGET}"
export PREFIX="/usr/local/php8"
./configure \
--prefix=${PREFIX} \
--with-apxs2="/usr/local/apache2/bin/apxs" \
--with-config-file-path="${PREFIX}/lib" \
--with-config-file-scan-dir="${PREFIX}/php.d" \
--with-iconv="/usr/local" \
--with-openssl=${SSL} \
--with-openssl-dir=${SSL} \
--with-zlib=/usr \
--with-zlib-dir=/usr \
--enable-gd \
--with-external-gd \
--with-bz2="/usr/local" \
--enable-exif \
--enable-soap \
--enable-ftp \
--enable-sockets \
--enable-mbstring \
--enable-calendar \
--enable-bcmath \
--enable-pcntl \
--enable-shmop \
--enable-sysvmsg \
--enable-sysvsem \
--enable-sysvshm \
--with-curl="/usr/local" \
--with-mysql-sock=/tmp/mysql.sock \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-kerberos=/usr \
--with-imap-ssl=/usr \
--with-gettext=/usr/local \
--with-pear \
--disable-huge-code-pages \
--disable-opcache-jit \
CC="${GCC}/bin/gcc" \
CXX="${GCC}/bin/g++" \
CPP="${GCC}/bin/cpp" \
CPPFLAGS="-I${SSL}/include -I/usr/local/include -I/usr/include" \
CFLAGS="${CFLAGS}" \
CXXFLAGS="${CFLAGS}" \
LDFLAGS="-L${SSL}/lib -L${GCC}/lib -L/usr/local/lib -L/usr/lib"
make
make test > check.log
|
注)「¥」は実際には半角の「\」(バックスラッシュ)
PHP 8.0 で追加された JITコンパイラですが、インテルのx86, x64アーキテクチャしかサポートされていないのは PHP 8.1でも同じです。そのため "--disable-opcache-jit" オプションを指定して機能を無効化しています。
2. ソース修正
以前からウチの環境(Mac mini G4)向けに行っているソース修正と、PHP 8.0で追加した修正を PHP 8.1でもやっておきます。
"Zend/zend_alloc.c"
#ifndef __APPLE__
# define ZEND_MM_FD -1
#else
# include <mach/vm_statistics.h>
/* Mac allows to track anonymous page via vmmap per TAG id.
* user land applications are allowed to take from 240 to 255.
*/
# define ZEND_MM_FD VM_MAKE_TAG(250U)
#endif
|
↓
//#ifndef __APPLE__
# define ZEND_MM_FD -1
//#else
//# include <mach/vm_statistics.h>
/* Mac allows to track anonymous page via vmmap per TAG id.
* user land applications are allowed to take from 240 to 255.
*/
//# define ZEND_MM_FD VM_MAKE_TAG(250U)
//#endif/code>
|
Mac OS(__APPLE__ )のときは mmap() の第5引数に指定するファイルディスクリプタに特別な値を指定するようにしているけど、ウチのように古〜い Mac OS X にはこんな機能はないので、これを無効化しています。
"Zend/zend.c"
static ZEND_COLD void get_filename_lineno(int type, zend_string **filename, uint32_t *lineno) {
/* Obtain relevant filename and lineno */
switch (type) {
case E_CORE_ERROR:
case E_CORE_WARNING:
*filename = NULL;
*lineno = 0;
break;
case E_PARSE:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
case E_ERROR:
case E_NOTICE:
case E_STRICT:
case E_DEPRECATED:
case E_WARNING:
case E_USER_ERROR:
case E_USER_WARNING:
case E_USER_NOTICE:
case E_USER_DEPRECATED:
case E_RECOVERABLE_ERROR:
if (zend_is_compiling()) {
#if defined(HAVE_JIT)
*filename = zend_get_compiled_filename();
*lineno = zend_get_compiled_lineno();
#else
*filename = NULL;
*lineno = 0;
#endif
} else if (zend_is_executing()) {
*filename = zend_get_executed_filename_ex();
*lineno = zend_get_executed_lineno();
} else {
*filename = NULL;
*lineno = 0;
}
break;
default:
*filename = NULL;
*lineno = 0;
break;
}
if (!*filename) {
*filename = ZSTR_KNOWN(ZEND_STR_UNKNOWN_CAPITALIZED);
}
}
|
PHP 8.0で作り込まれたバグです(ワタシはそう思ってます^^;)。PHP 8.1でも変わらず残っていましたので、同じ修正(defined(HAVE_JIT) )を当てておきます。
"ext/openssl/openssl.c"
#if PHP_OPENSSL_API_VERSION >= 0x10100 && !defined (LIBRESSL_VERSION_NUMBER)
ASN1_INTEGER_set_int64(X509_get_serialNumber(new_cert), serial);
#else
ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
#endif
|
↓
//#if PHP_OPENSSL_API_VERSION >= 0x10100 && !defined (LIBRESSL_VERSION_NUMBER)
// ASN1_INTEGER_set_int64(X509_get_serialNumber(new_cert), serial);
//#else
ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
//#endif
|
3349行からの翻訳制御がウチの環境だと何故か ASN1_INTEGER_set_int64() の方になってしまうようで、コンパイルエラーになるのです。ウチの環境(Mac mini G4)には "ASN1_INTEGER_set_int64" はありませんので、無条件に "ASN1_INTEGER_set()" にしています。
3. fiber(新機能)対応
PHP 8.1 で追加された新しい機能に fiber(ファイバー)があります。これはPHPで非同期処理を行えるようにする機能だそうですが、一部アセンブリ言語を使用して記述されています。
"Zend/asm" 配下にある一連のソースがそれで、多くのCPU(x86, x64, ARM, ppc32, ppc64, MIPS, RISC-V)や OSに対応していることが見てとれます。
ウチの Mac mini G4 で使われるのは "make_ppc32_sysv_macho_gas.S", "jump_ppc32_sysv_macho_gas.S" なのですが、コイツがウチのような古〜い Mac OS Xでは syntaxエラ−になってビルドが失敗してしまうのです。おそらく構文が微妙に違うのでしょうな。
configureオプションに "--disable-fiber-asm" を指定すればこのアセンブリソースを使用せずにビルドできるのですが、そうすると今度は "getcontext", "makecontext", "swapcontext" がリンクエラー(undef)になってしまうのです。ウチの Mac OS X にはこれらのコンテキスト制御機能が提供されていないのですね。
どうせ fiber新機能はウチの Blogで使うことはないので、ビルドさえ突破できれば良くまともに動く必要はないという方針で行くことにします。なので、この修正は asで syntaxエラーが起きなきゃいいっていう代物なので全く参考にはなりません。ご注意ください。
"Zend/asm/make_ppc32_sysv_macho_gas.S"
〜先頭のコメント部分は省略〜
.machine ppc
.text
.globl _make_fcontext
.align 2
_make_fcontext:
# save return address into R6
mflr r6
# first arg of make_fcontext() == top address of context-function
# shift address in R3 to lower 16 byte boundary
clrrwi r3, r3, 4
# reserve space for context-data on context-stack
# including 64 byte of linkage + parameter area (R1 16 == 0)
subi r3, r3, 336
# third arg of make_fcontext() == address of context-function
stw r5, 240(r3)
# set back-chain to zero
li r0, 0
stw r0, 244(r3)
mffs f0 ; load FPSCR
stfd f0, 144(r3) ; save FPSCR
# compute address of returned transfer_t
addi r0, r3, 252
mr r4, r0
stw r4, 228(r3)
# load LR
mflr r0
# jump to label 1
bl 1f
1:
# load LR into R4
mflr r4
# compute abs address of label finish
addi r4, r4, lo16(finish - 1b)
# restore LR
mtlr r0
# save address of finish as return-address for context-function
# will be entered after context-function returns
stw r4, 236(r3)
# restore return address from R6
mtlr r6
blr ; return pointer to context-data
finish:
# save return address into R0
mflr r0
# save return address on stack, set up stack frame
stw r0, 4(r1)
# allocate stack space, R1 16 == 0
stwu r1, -16(r1)
# exit code is zero
li r3, 0
# exit application
bl L_exit$stub
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
.align 5
L_exit$stub:
.indirect_symbol _exit
mflr r0
bcl 20,31,"L00000000001$spb"
"L00000000001$spb":
mflr r11
addis r11,r11,ha16(L_exit$lazy_ptr-"L00000000001$spb")
mtlr r0
lwzu r12,lo16(L_exit$lazy_ptr-"L00000000001$spb")(r11)
mtctr r12
bctr
.lazy_symbol_pointer
L_exit$lazy_ptr:
.indirect_symbol _exit
.long dyld_stub_binding_helper
.subsections_via_symbols
|
"Zend/asm/jump_ppc32_sysv_macho_gas.S"
〜先頭のコメント部分は省略〜
.machine ppc
.text
.globl _jump_fcontext
.align 2
_jump_fcontext:
; reserve space on stack
subi r1, r1, 244
stfd f14, 0(r1) ; save F14
stfd f15, 8(r1) ; save F15
stfd f16, 16(r1) ; save F16
stfd f17, 24(r1) ; save F17
stfd f18, 32(r1) ; save F18
stfd f19, 40(r1) ; save F19
stfd f20, 48(r1) ; save F20
stfd f21, 56(r1) ; save F21
stfd f22, 64(r1) ; save F22
stfd f23, 72(r1) ; save F23
stfd f24, 80(r1) ; save F24
stfd f25, 88(r1) ; save F25
stfd f26, 96(r1) ; save F26
stfd f27, 104(r1) ; save F27
stfd f28, 112(r1) ; save F28
stfd f29, 120(r1) ; save F29
stfd f30, 128(r1) ; save F30
stfd f31, 136(r1) ; save F31
mffs f0 ; load FPSCR
stfd f0, 144(r1) ; save FPSCR
stw r13, 152(r1) ; save R13
stw r14, 156(r1) ; save R14
stw r15, 160(r1) ; save R15
stw r16, 164(r1) ; save R16
stw r17, 168(r1) ; save R17
stw r18, 172(r1) ; save R18
stw r19, 176(r1) ; save R19
stw r20, 180(r1) ; save R20
stw r21, 184(r1) ; save R21
stw r22, 188(r1) ; save R22
stw r23, 192(r1) ; save R23
stw r24, 196(r1) ; save R24
stw r25, 200(r1) ; save R25
stw r26, 204(r1) ; save R26
stw r27, 208(r1) ; save R27
stw r28, 212(r1) ; save R28
stw r29, 216(r1) ; save R29
stw r30, 220(r1) ; save R30
stw r31, 224(r1) ; save R31
stw r3, 228(r1) ; save hidden
# save CR
mfcr r0
stw r0, 232(r1)
# save LR
mflr r0
stw r0, 236(r1)
# save LR as PC
stw r0, 240(r1)
# store RSP (pointing to context-data) in R6
mr r6, r1
# restore RSP (pointing to context-data) from R4
mr r1, r4
lfd f14, 0(r1) ; restore F14
lfd f15, 8(r1) ; restore F15
lfd f16, 16(r1) ; restore F16
lfd f17, 24(r1) ; restore F17
lfd f18, 32(r1) ; restore F18
lfd f19, 40(r1) ; restore F19
lfd f20, 48(r1) ; restore F20
lfd f21, 56(r1) ; restore F21
lfd f22, 64(r1) ; restore F22
lfd f23, 72(r1) ; restore F23
lfd f24, 80(r1) ; restore F24
lfd f25, 88(r1) ; restore F25
lfd f26, 96(r1) ; restore F26
lfd f27, 104(r1) ; restore F27
lfd f28, 112(r1) ; restore F28
lfd f29, 120(r1) ; restore F29
lfd f30, 128(r1) ; restore F30
lfd f31, 136(r1) ; restore F31
lfd f0, 144(r1) ; load FPSCR
mtfsf 0xff, f0 ; restore FPSCR
lwz r13, 152(r1) ; restore R13
lwz r14, 156(r1) ; restore R14
lwz r15, 160(r1) ; restore R15
lwz r16, 164(r1) ; restore R16
lwz r17, 168(r1) ; restore R17
lwz r18, 172(r1) ; restore R18
lwz r19, 176(r1) ; restore R19
lwz r20, 180(r1) ; restore R20
lwz r21, 184(r1) ; restore R21
lwz r22, 188(r1) ; restore R22
lwz r23, 192(r1) ; restore R23
lwz r24, 196(r1) ; restore R24
lwz r25, 200(r1) ; restore R25
lwz r26, 204(r1) ; restore R26
lwz r27, 208(r1) ; restore R27
lwz r28, 212(r1) ; restore R28
lwz r29, 216(r1) ; restore R29
lwz r30, 220(r1) ; restore R30
lwz r31, 224(r1) ; restore R31
lwz r3, 228(r1) ; restore hidden
# restore CR
lwz r0, 232(r1)
mtcr r0
# restore LR
lwz r0, 236(r1)
mtlr r0
# load PC
lwz r0, 240(r1)
# restore CTR
mtctr r0
# adjust stack
addi r1, r1, 244
# return transfer_t
stw r6, 0(r3)
stw r5, 4(r3)
# jump to context
bctr
|
修正は赤字部分。殆どがコメント記述方法の修正です。ウチの as では、ニーモニック後ろのコメントは "#" からではなく ";" から始める必要があるようなので。
それ以外には exit(0); の呼び出しですね。元ソースは ._exit@plt へ分岐していたのですが、それだと _exit がリンクエラー(undef)になってしまいました。そのため gcc で exit(0); のアセンブリソースを出力させて当該処理をコピペしました。
|