blog.heartyfluid

勉強したることども

php-build で PHP8.1 を WSL2 上の Ubuntu 22.4 LTS にインストールする

ふだん PHP は Docker 経由もしくは Windows + Scoop で利用しています。

bashalog.c-brains.jp

今回、表題のとおり WSL2 上の Ubuntu で PHP8.1 が使いたくなりました。

$ php -v
Command 'php' not found, but can be installed with:
sudo apt install php8.1-cli  # version 8.1.2-1ubuntu2.9, or
sudo apt install php-cli     # version 2:8.1+92ubuntu1

APT のパッケージとしても提供されているようだけれど、どうせなら Windows + Scoop のように任意のバージョンが使えるようにしたいところです。

そこで、 php-build を導入して任意のバージョンの PHP がビルドできるようにしたうえで、 direnv でバージョンが切り替えられるようにすることにしました。

tenkoma.hatenablog.com

php-build のインストール

まずは php-build のコード一式を取得してインストールします。公式ドキュメントいうところの standalone での導入にあたります。

$ git clone https://github.com/php-build/php-build.git
$ cd php-build/
$ PREFIX=$HOME/local ./install.sh
$ php-build/bin/php-build --version
php-build v0.11.0dev

php-buildPHP をビルドする

本校執筆時点での PHP8.1 系最新バージョンのビルドを試みます。

$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
tar (child): bzip2: Cannot exec: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now
-----------------------------------------
[...]

bzip2 が入っていませんでした。インストールして再試行します。

$ sudo apt install bzip2
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: in `/tmp/php-build/source/8.1.13':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details
-----------------------------------------
[...]

C コンパイラが入っていませんでした。インストールして再試行。

$ sudo apt install build-essential
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: The pkg-config script could not be found or is too old.  Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.

Alternatively, you may set the environment variables LIBXML_CFLAGS
and LIBXML_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

To get pkg-config, see <http://pkg-config.freedesktop.org/>.
See `config.log' for more details
-----------------------------------------
[...]

phg-config が古すぎた。

$ sudo apt install pkg-config
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (libxml-2.0 >= 2.9.0) were not met:

No package 'libxml-2.0' found
[...]

libxml2 が足りない。

$ sudo apt install libxml2-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (openssl >= 1.0.2) were not met:

No package 'openssl' found
[...]

openssl が足りない。

$ sudo apt install libssl-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (sqlite3 >= 3.7.7) were not met:

No package 'sqlite3' found
[...]

sqlite3 が足りない。

$ sudo apt install libsqlite3-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (zlib >= 1.2.0.4) were not met:

No package 'zlib' found
[...]

zlib が足りない。

$ sudo apt install zlib1g-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Please reinstall the BZip2 distribution
-----------------------------------------
[...]

BZip2... さっき入れましたが。コマンドでなく development kit のほうが必要になったということかしら。

$ sudo apt install libbz2-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (libcurl >= 7.29.0) were not met:

No package 'libcurl' found
[...]

libcurl が足りない。

$ sudo apt install libcurl4-openssl-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (libpng) were not met:

No package 'libpng' found
[...]

libpng が足りない。

$ sudo apt install libpng-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (libjpeg) were not met:

No package 'libjpeg' found
[...]

libjpeg が足りない。

$ sudo apt install libjpeg-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (oniguruma) were not met:

No package 'oniguruma' found
[...]

oniguruma が足りない。

$ sudo apt install libonig-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Please reinstall readline - I cannot find readline.h
-----------------------------------------
[...]

readline が足りない。

$ sudo apt install libreadline-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Cannot find libtidy
-----------------------------------------
[...]

libtidy が足りない。

$ sudo apt install libtidy-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: error: Package requirements (libxslt >= 1.1.0) were not met:

No package 'libxslt' found
[...]

libxslt が足りない。

$ sudo apt install libxslt1-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
No package 'libzip' found
[...]

libzip が足りない。

$ sudo apt install libzip-dev
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[...]
-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
In file included from /tmp/php-build/source/8.1.13/ext/opcache/jit/zend_jit.c:705:
/tmp/php-build/source/8.1.13/ext/opcache/jit/zend_jit.c: In function ‘zend_jit_startup’:
/tmp/php-build/source/8.1.13/ext/opcache/jit/dynasm/dasm_x86.h:127:19: warning: array subscript -10 is outside array bounds of ‘void *[38]’ [-Warray-bounds]
  127 |   D->globals = gl - 10;  /* Negative bias to compensate for locals. */
      |                ~~~^~~~
In file included from /tmp/php-build/source/8.1.13/ext/opcache/jit/zend_jit.c:763:
/tmp/php-build/source/8.1.13/ext/opcache/jit/zend_jit_x86.dasc:143:14: note: while referencing ‘dasm_labels’
  143 | static void* dasm_labels[zend_lb_MAX];
      |              ^~~~~~~~~~~
PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.
-----------------------------------------
[...]

何か一目ではわからないエラーが出てきました。エラーメッセージの一部でぐぐってみると、先達がいました。あらまほしきことです。

qiita.com

autoconf を入れましょう。

$ sudo apt install autoconf
$ php-build/bin/php-build -i development 8.1.13 ~/php/8/8.1.13
[Info]: Loaded extension plugin
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
[Info]: Loaded github Plugin.
[Info]: Loaded uprofiler Plugin.
[Info]: Loaded xdebug Plugin.
[Info]: Loaded xhprof Plugin.
[Info]: Loaded zendopcache Plugin.
[Info]: php.ini-development gets used as php.ini
[Info]: Building 8.1.13 into /home/ykagata/php/8/8.1.13
[Skipping]: Already downloaded and extracted https://www.php.net/distributions/php-8.1.13.tar.bz2
[Preparing]: /tmp/php-build/source/8.1.13
[Compiling]: /tmp/php-build/source/8.1.13
[xdebug]: Installing version 3.2.0
[Skipping]: Already downloaded http://xdebug.org/files/xdebug-3.2.0.tgz
[xdebug]: Compiling xdebug in /tmp/php-build/source/xdebug-3.2.0
[xdebug]: Installing xdebug configuration in /home/ykagata/php/8/8.1.13/etc/conf.d/xdebug.ini
[xdebug]: Cleaning up.
Makefile:243: warning: overriding recipe for target 'test'
Makefile:136: warning: ignoring old recipe for target 'test'
[Info]: Enabling Opcache...
[Info]: Done
[Info]: The Log File is not empty, but the Build did not fail. Maybe just warnings got logged. You can review the log in /tmp/php-build.8.1.13.20221223223630.log or rebuild with '--verbose' option
[Success]: Built 8.1.13 successfully.
$ ~/php/8/8.1.13/bin/php -v
PHP 8.1.13 (cli) (built: Dec 23 2022 22:38:51) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.13, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.13, Copyright (c), by Zend Technologies
    with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans

Sehr gut.

記録のため、必要なパッケージをひとつひとつ探索する一部始終を書き起こしました。いったんわかってしまえば次回以降は、ここまででインストールしたパッケージを最初に一括で apt install すれば十分ですね。

direnvPHP にパスを通す

direnv は APT でインストールできます。

$ sudo apt install direnv

当該ディレクトリで必要な環境変数を定義するファイル .envrc を作成します。以下のコマンドでテキストエディタが開きます。

$ direnv edit .

次のとおり追記して保存し、テキストエディタを抜けます。

PATH_add $HOME/php/8/8.1.13/bin

作成した .envrc の適用を許可します。

$ direnv allow

大事なことを忘れていました。 ~/.bash_profile に以下を追記します。

eval "$(direnv hook bash)"

direnvを活用して楽々環境変数管理【Ubuntu】 | Abillyzによれば

~/.bashrcにフックする設定をする。 ※WSLのUbuntuはデフォルトで読まないので~/.bash_profileに設定

とのことで、 WSL 以外では ~/.bashrc に書けばよいもよう。

編集した ~/.bash_profile をリロードすれば、できあがりです。

$ source ~/.bash_profile
direnv: loading ~/.envrc
direnv: export ~PATH
$ php -v
PHP 8.1.13 (cli) (built: Dec 23 2022 22:38:51) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.13, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.13, Copyright (c), by Zend Technologies
    with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans

別のバージョンの PHP が使いたくなったら、同様の要領でビルドして、 direnv でパスを通してやれば ok です。