PHP 8 をビルドする

11 min読了の目安(約10100字TECH技術記事

はじめまして。最近プログラミングを初めた、めもりー(https://twitter.com/m3m0r7) です。
お手柔らかにお願いします。ようやく待望の PHP 8 が出たということで CentOS 7 上に PHP 8 をビルドしてみましょう。

準備

PHP8 は執筆時点では RC で、下記にて公開されています。

https://downloads.php.net/~carusogabriel/

今回使用するのは php-8.0.0rc1.tar.gz です。というわけで下記のように取得します。

$ wget https://downloads.php.net/~carusogabriel/php-8.0.0rc1.tar.gz
$ tar zxvf php-8.0.0rc1.tar.gz
$ cd php-8.0.0rc1

./configure を実行する

ビルドをするにあたり、事前に ./configure を実行して Makefile とそれに関連するファイルを作成しておく必要があります。
また PHP のビルドは ./configure しながら足りないモジュールは何かを見ていき、必要なものをインストールしていくと、よいです。
PHP 7.3 より ./configure で出力されるエラーで何が足りないのかを視覚的にわかりやすいように変更が入っています。そのため、私のような初心者でもエラーを見ればひと目で何が足りないのかわかります。

ということで ./configure を走らせてみます。

./configure

実行していると下記のようにエラーがでます。

...
checking for cc... no
checking for gcc... no
configure: error: in `/php-8.0.0rc1':
configure: error: no acceptable C compiler found in $PATH

コンパイラがないということなので、下記のように入れます。

...
$ sudo yum install -y gcc-c++

もう一度 ./configure を実行します。

$ ./configure

次に別のエラーとして下記のようにでます。

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

No package 'libxml-2.0' found

libxml が足りないということで、これも yum でインストールします。

$ sudo yum install -y libxml2-devel

もう一度 ./configure を実行します。

$ ./configure

次に下記のエラーがでました。

configure: error: Package requirements (sqlite3 > 3.7.4) were not met:

No package 'sqlite3' found

下記のようにインストールします。

$ sudo yum install -y sqlite-devel

もう一度 ./configure を走らせます。

$ ./configure

進めていき、下記のように表示されたら ./configure に成功ということになります。

...
+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE. By continuing this installation  |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

make でビルドする

ということで make を実行します。画像のように make のオプションに -j があり、どのくらい並列に進めるかを指定することができます。
ご自身が使用されているマシンの CPU の数を指定するのが一般的です。とはいえ、覚えてないという方もいると思うので $(nproc) を脳死で付け加えると良いです。

make を実行する前に make そのものが必要なため、インストールしておきます。

$ sudo yum install -y make

インストールを終えたら下記のように make します。

$ make -j$(nproc)

ログが流れ、最終的に下記のように表示されればビルドが成功したことになります。

...
Build complete.
Don't forget to run 'make test'.

最後にパスを通すため make install を実行します。

$ make install

実行してみる

これでインストールが完了です。 php -v を実行して PHP のバージョンを見てみましょう。

$ php -v

下記のように表示されたら PHP 8 がインストールされたことがわかります。

PHP 8.0.0rc1 (cli) (built: Oct  4 2020 02:38:28) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
Removing intermediate container 3f2e94e82549

インストールされているモジュールを php -m で出力してみます。

$ php -m

[PHP Modules]
Core
ctype
date
dom
fileinfo
filter
hash
iconv
json
libxml
pcre
PDO
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter

[Zend Modules]

PHP の過去のバージョンのビルド時と比べると依存関係を剥がしていっているのか、だいぶ少ないということがわかります。

パラメータを増やす

さて、現状インストールした PHP は、先程 php -m を実行してわかるように、いわゆる初心者装備です。ラスボス(本番環境)で初心者装備で戦うのはよほどのマゾでなければ、やらないかと思います。
ということで ./configure 時のパラメータを増やします。私達が普段使用するモジュールは以下でしょうか。

mbstring
pdo_mysql
gd
zip
openssl
fpm

それぞれ下記のようなパラメータになります。

モジュール名 パラメータ
mbstring --enable-mbstring
pdo_mysql --with-pdo-mysql
gd --enable-gd (オプションとして: --with-webpm, --with-jpeg, --with-xpm, --with-freetype)
zip --with-zip
openssl --with-openssl
fpm --enable-fpm

これらのパラメータを ./configure に付与し、実行します。

$ ./configure --enable-mbstring \
    	      --with-pdo-mysql \
    	      --enable-gd \
    	      --with-webpm \
    	      --with-jpeg \
    	      --with-xpm \
    	      --with-freetype \
    	      --with-zip \
    	      --with-openssl \
    	      --enable-fpm

実行すると、初めに

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

No package 'oniguruma' found

上記が表示されます。onigurumambstring で使用しているライブラリということで、これをインストールします。

$ sudo yum install -y oniguruma-devel

インストール後 ./configure を同じように実行してみます。

$ ./configure --enable-mbstring \
    	      --with-pdo-mysql \
    	      --enable-gd \
    	      --with-webpm \
    	      --with-jpeg \
    	      --with-xpm \
    	      --with-freetype \
    	      --with-zip \
    	      --with-openssl \
    	      --enable-fpm

進めていくと下記のようにエラーが表示されます。

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

No package 'openssl' found

openssl がないというエラーなので、これもインストールします。

$ sudo yum install -y openssl-devel

また同じように ./configure を実行します。

$ ./configure --enable-mbstring \
    	      --with-pdo-mysql \
    	      --enable-gd \
    	      --with-webpm \
    	      --with-jpeg \
    	      --with-xpm \
    	      --with-freetype \
    	      --with-zip \
    	      --with-openssl \
    	      --enable-fpm

次は下記のように libpng がないというエラーが表示されます。

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

No package 'libpng' found

これも先程と同様に下記のように libpng をインストールします。

$ sudo yum install -y libpng-devel

次も同様に ./configure を実行すると libjpeg がないと出るので、同様に解決します。

$ sudo yum install -y libjpeg-devel

同様に進めると xpm がないと表示されるので、これもまた同様に解決します。

$ sudo yum install -y libXpm-devel

次は freetype2 がないというエラーが出るので、これも同様に解決します。

$ sudo yum install -y freetype-devel

さて、もう一度 ./configure を実行してみましょう。

$ ./configure --enable-mbstring \
    	      --with-pdo-mysql \
    	      --enable-gd \
    	      --with-jpeg \
    	      --with-xpm \
    	      --with-freetype \
    	      --with-zip \
    	      --with-openssl \
    	      --enable-fpm

実行していくと下記のように libzip がないと下記のように表示されます。

configure: error: Package requirements (libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0) were not met:

No package 'libzip' found
No package 'libzip' found
No package 'libzip' found

これも同様に解決したいのですが CentOS のデフォルトの libzip だとバージョンが 0.10 となり yum でのインストールでは詰みます。
PHP の野良ビルドで比較的辛いのは --with-zip を有効にした際の必要モジュールのインストールだと思います。

ということで libzip は自前でビルドする必要があります。

libzip: https://libzip.org/download/

では、早速ビルドします。

$ wget https://libzip.org/download/libzip-1.7.3.tar.gz
$ tar zxvf libzip-1.7.3.tar.gz
$ cd libzip-1.7.3

libzipcmake のバージョン 3.0.2 以上を使用してビルドの下準備をする必要があるのですが、その cmake も yum で入れる場合、バージョンが 2 となっており、ここでもまた詰みます。

したがって cmake を更にビルドする必要があります。

CMake: https://github.com/Kitware/CMake

ビルドすることにより、バイナリを使用する際の環境変数をセットするなどのステップを飛ばせるので、相対的に楽になります。

git コマンドがない場合は予め入れておきます。

$ sudo yum install -y git

公式の手順に乗っ取り、下記のように実行します。

$ git clone https://github.com/Kitware/CMake
$ cd CMake
$ ./bootstrap && make -j$(mnproc) && sudo make install

cmake のビルドは割と時間がかかるので、気長がに待ちます。その間うちのねこの画像でも見ててください。

ディレクトリを戻します。

cd ../

そして cmake, make 及び make install を実行します。

$ ./configure
$ cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/libzip
$ make -j$(nproc)
$ make install

また、libzip の pkgconfig までの環境変数として PKG_CONFIG_PATH を指定してあげる必要があるので、下記のようにします。

export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/libzip/lib64/pkgconfig"

PHP のディレクトリに戻ります。

cd ../

その後、改めて ./configure を実行してみましょう。

$ ./configure --enable-mbstring \
    	    --with-pdo-mysql \
    	    --enable-gd \
    	    --with-jpeg \
    	    --with-xpm \
    	    --with-freetype \
    	    --with-zip \
    	    --with-openssl \
    	    --enable-fpm

これで必要なモジュールが揃いました。ということで make します。

$ make -j$(nproc)
$ sudo make install

進めていくと、下記のように出てくるので php-fpm がインストールされたことがわかります。

...
Installing PHP FPM binary:        /usr/local/sbin/
Installing PHP FPM defconfig:     /usr/local/etc/
Installing PHP FPM man page:      /usr/local/php/man/man8/
Installing PHP FPM status page:   /usr/local/php/php/fpm/
...

上記が完了したら再度インストールされたモジュールを php -m で見てみます。

$ php -m

[PHP Modules]
Core
ctype
date
dom
fileinfo
filter
gd           # 追加されています
hash
iconv
json
libxml
mbstring     # 追加されています
mysqlnd
openssl      # 追加されています
pcre
PDO
pdo_mysql    # 追加されています
pdo_sqlite
Phar
posix
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zip          # 追加されています

[Zend Modules]

指定したパラメータがモジュールとして追加されていることがわかりました。

実行したコマンドをまとめると下記です。

FROM centos:centos7

$ yum update && \
yum upgrade && \
yum install -y epel-release && \
yum install -y wget \
               gcc-c++ \
               libxml2-devel \
               sqlite-devel \
               oniguruma-devel \
               openssl-devel \
               libpng-devel \
               libjpeg-devel \
               libXpm-devel \
               freetype-devel \
               make \
               git

$ wget https://downloads.php.net/~carusogabriel/php-8.0.0rc1.tar.gz && \
tar zxvf php-8.0.0rc1.tar.gz && \
cd php-8.0.0rc1

$ wget https://libzip.org/download/libzip-1.7.3.tar.gz && \
tar zxvf libzip-1.7.3.tar.gz

$ git clone https://github.com/Kitware/CMake && \
cd CMake && \
./bootstrap && \
make && \
sudo make install

$ cd ../libzip-1.7.3 &&
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/libzip && \
make -j$(mnproc) && \
sudo make install

$ cd ../ && \
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/libzip/lib64/pkgconfig" && \
./configure --enable-mbstring \
    	    --with-pdo-mysql \
    	    --enable-gd \
    	    --with-jpeg \
    	    --with-xpm \
    	    --with-freetype \
    	    --with-zip \
    	    --with-openssl \
    	    --enable-fpm && \ 
make -j$(nproc) && \
sudo make install

$ php -v
$ php -m

以上です。