phpenv+php-buildでのDebug用PHPのビルド

2019-10-14
PHP
php-env
php-build

概要

phpenv, php-buildを使ってPHPをビルドする際に、同一バージョンを別名で異なるオプションでビルドする手順。
例としてDebugオプション--enable-debug を付けた例ですが、オプションを足したり引いたりするやり方は共通ですので、任意のオプションを付けたPHPを分かりやすいpostfixを付けて管理する方法と思えば良いです。

手順

phpenv, php-buildの使い方は、それぞれの公式サイトを見てください。
今回の例では、7.4snapshotから7.4snapshot_debugというDebug用のPHPビルドdefinitionを作成します。

php-buildは、definitionsというディレクトリにそれぞれのPHPバージョンのインストール時の設定等を書いてますので、それをコピーします。

1
2
$ cd php-build/share/php-build/definitions
$ cp 7.4snapshot 7.4snapshot_debug

7.4snapshot_debugの編集

変更前

1
2
install_package_from_github PHP-7.4
enable_builtin_opcache

変更後

1
2
3
4
5
6
7
8
export PHP_BUILD_EXTRA_MAKE_ARGUMENTS="-j4"
export PHP_BUILD_TMPDIR=/home/hanhan/php-srcs
configure_option "--enable-maintainer-zts"
configure_option "--enable-debug"
configure_option "--with-ffi"
configure_option -D "--disable-debug"
install_package_from_github PHP-7.4
enable_builtin_opcache

編集内容の解説

  • PHP_BUILD_EXTRA_MAKE_ARGUMENTS="-j4"
    makeを行う際の追加のオプション指定です。CPUコアが余っているので-j4で4コア使うように指定。※ドキュメントに記載なし
  • PHP_BUILD_TMPDIR=/home/hanhan/php-srcs
    デフォルトでは/tmpにソースコードがダウンロードされるのでOSに消されてしまいます。自分に都合の良い場所にソースをダウンロードして、いつでもソースコードを読めるようにしています。ソースコードリーディングが主目的なのでこれが大事。※ドキュメントに記載なし
    この指定をdefinitionsで行うのは筋が悪いです。install コマンド実行時にシェル変数で指定してあげましょう。(後述)
  • configure_option
    追加のオプションをこれで指定します。 ※man/php-build.5に記載があります。
  • configure_option -D
    php-buidのデフォルトオプションで指定されているものを取り消すオプションです。デフォルトオプションはshare/php-build/default_configure_optionsです。 ※man/php-build.5に記載があります。

インストール

通常通りです。

1
phpenv install 7.4snapshot-debug

2021-04-19 追記。

PHP_BUILD_TMPDIR は↑のdefinitions の記述からは削除しましょう。そして、下記のように install コマンド実行時に指定してしましょう。

1
PHP_BUILD_TMPDIR=/home/hanhan/php-srcs phpenv install 7.4snapshot-debug

※指定したディレクトリは予め作成しておいてください。そうすれば、php-build が必要な内部ディレクトリ構造を作ってくれます。

確認

1
2
3
4
5
$ php -v
PHP 7.4.0-dev (cli) (built: Oct 9 2019 16:35:21) ( ZTS DEBUG )
Copyright (c) The PHP Group
Zend Engine v3.4.0-dev, Copyright (c) Zend Technologies
with Zend OPcache v7.4.0-dev, Copyright (c), by Zend Technologies

ちゃんと( ZTS DEBUG )でインストールされてます。色んな方法試しましたが、参考リンクのhnwさんのブログでも記載があるように、この方法が一番php-buildに影響を与えることなく自分に都合の良いビルドが出来て楽ちんです。

ドキュメントは、manが用意されてますが、記載の無い便利な環境変数が沢山あります。php-build自体はシンプルなシェルスクリプトですので、是非読んでみると良いと思います。

参考リンク

phpenv
php-build
php-buildが便利だという話を補足します - hnwの日記

試行錯誤で得た知見

.phpenv/versionsのディレクトリ名をリネームしても駄目

symlinkで張り替えているだけだからイケるだろうと思いましたが、--with-config-file-scan-dir, --with-config-file-pathでパス直指定でiniファイルを読みに行くのでリネームは駄目でした。いやそんなconfigureオプション知らなかったよ…。

ちなみに、OpcacheとかのZendモジュールもphp.iniに絶対パスでロードの記述があるので、ディレクトリ名をリネームするとロードできなくなります。なのでディレクトリ名変更は駄目。

PHPRCという環境変数

設定ファイルパスを環境変数で指定することが出来ます。なので、ディレクトリ名を変更した上で、PHPRCで設定ファイルへのパスを通せば動かせなくはない。この場合も絶対パス指定のZendモジュール類が動かないのは変わらない。まあ、悪あがき。

例えば、こんな感じ。

1
export PHPRC=/home/hanhan/.phpenv/versions/7.3.7_debug/etc

まとめ

大した知見ではないのですが、どっかにまとめておかないとすぐ忘れそう&人に説明するの面倒くさいので、備忘録として残しました。これでみんなもPHPのソースコード読めるよ!

2021-04-19 追記

PHP_BUILD_TMPDIR について、誤解があったので追記しました。そもそも、コアな開発者が利用できます程度の扱いなので、ドキュメントには丁寧に書かれてなくて良いかなと思いました。

細かく言うと、php-buildinit 関数内で、ダウンロードしたPHPソースコードを展開するためのディレクトリを準備するのですが、PHP_BUILD_TMPDIR で指定されたディレクトリが存在する場合は、そっちを使ってくれます。ディレクトリが存在しない場合は、/tmp が使われます。