🏠

[PHP day.25] phpenv で php 8 をビルドする on macOS

2020/12/25に公開

PHP Advent Calendar 2020 25日目のエントリです。
24日目は kasyuu さん[1]名前で呼べると色々と幸せになれるかもしれないphp関連の用語あれこれ でした。読んだのですが覚えて正しく使えるようになりたいと思いました。[2]

大変便利なんだけど何かと辛い phpenv で、11/26 にリリースされた php 8 をビルドできました。
このくらい (12/25) にはできるようになってそうと思って早々に 11/6 に登録していたのですが、できて良かったです。[3]

環境情報

実験が成功した環境を記述します。

  • MacBook Air (Retina, 13-inch, 2020)

    • macOS Catalina 10.15.7
  • phpenv v0.9.0-rc.1

    • on anyenv 1.1.2
  • インストール済みの関連ライブラリ

    ↓が使用されたはず、と思っています(brew info で確認)

    brew install openssl     # 1.1.1i
    brew install bzip2       # 1.0.8
    brew install libiconv    # 1.16
    brew install icu4c       # 67.1
    brew install tidy-html5  # 5.6.0
    brew install libzip      # 1.7.3
    brew install libxml2     # 2.9.10
    brew install zlib        # 1.2.11
    brew install libedit     # 20191231-3.1
    

    refs : https://github.com/sogaoh/mba-provisioner/blob/master/roles/packages/vars/main.yml#L45-L53

  • PHPビルド時のオプション

    ↓が使用されたはず、と思っています

     export PHP_BUILD_CONFIGURE_OPTS="\
     --disable-fpm \
     --disable-phpdbg \
     --enable-debug \
     --with-openssl=/usr/local/opt/openssl \
     --with-bz2=/usr/local/opt/bzip2 \
     --with-iconv=/usr/local/opt/libiconv \
     --with-icu-dir=/usr/local/opt/icu4c \
     --with-tidy=/usr/local/opt/tidy-html5 \
     --with-libzip=/usr/local/opt/libzip \
     --with-libxml-dir=/usr/local/opt/libxml2 \
     --with-zlib \
     --with-zlib-dir=/usr/local/opt/zlib \
     --with-libedit=/usr/local/opt/libedit"  
    

    refs : https://github.com/sogaoh/mba-provisioner/blob/master/roles/dotfiles/files/.zshrc#L125-L163

8/10 頃に PHP 7.4 をビルドしようとして悪戦苦闘していたTweetが残っているのですが、PHP 8 をビルドするのに際して追加のライブラリインストールやビルドオプションの調整は必要なかったです。

ちなみに、悪戦苦闘の跡

コケては情報を探す、を繰り返して辿り着いたようです。。
そして、やっと記事になった。。

phpenv で PHP 8 をビルド

実はやっぱり先人がいたようで、macOS に phpenv で PHP 8.0 をインストールする - Qiita を見ちゃってからやりました。
ということで、手順は以下で完了です。

  1. phpenv update (コンソール出力フルバージョン在中)
    
    ❯ phpenv -v
    phpenv v0.9.0-rc.1
    
    ~
    ❯ phpenv update
    warning: Pulling without specifying how to reconcile divergent branches is
    discouraged. You can squelch this message by running one of the following
    commands sometime before your next pull:
    
      git config pull.rebase false  # merge (the default strategy)
      git config pull.rebase true   # rebase
      git config pull.ff only       # fast-forward only
    
    You can replace "git config" with "git config --global" to set a default
    preference for all repositories. You can also pass --rebase, --no-rebase,
    or --ff-only on the command line to override the configured default per
    invocation.
    
    remote: Enumerating objects: 602, done.
    remote: Counting objects: 100% (602/602), done.
    remote: Compressing objects: 100% (106/106), done.
    remote: Total 647 (delta 528), reused 515 (delta 473), pack-reused 45
    Receiving objects: 100% (647/647), 100.75 KiB | 355.00 KiB/s, done.
    Resolving deltas: 100% (544/544), completed with 125 local objects.
    From https://github.com/php-build/php-build
       8bb9434..5a3d184  master     -> origin/master
    Updating 8bb9434..5a3d184
    Fast-forward
     .github/workflows/ci.yml                |  69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     .travis.yml                             |  93 +++++++++++-------------------------------------------------------------------------
     CHANGELOG.md                            |   7 ++++---
     bin/php-build                           |  93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
     build-openssl-1.0.sh                    |  58 +++++++++++++++++++++++++++++++++++++++++++++-------
     install-dependencies.sh                 | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     run-tests.sh                            |   3 ++-
     share/php-build/definitions/5.2.17      |   1 +
     share/php-build/definitions/5.3.10      |   1 +
     share/php-build/definitions/5.3.11      |   1 +
     share/php-build/definitions/5.3.12      |   1 +
     share/php-build/definitions/5.3.13      |   1 +
     share/php-build/definitions/5.3.14      |   1 +
     share/php-build/definitions/5.3.15      |   1 +
     share/php-build/definitions/5.3.16      |   1 +
     share/php-build/definitions/5.3.17      |   1 +
     share/php-build/definitions/5.3.18      |   1 +
     share/php-build/definitions/5.3.19      |   1 +
     share/php-build/definitions/5.3.2       |   1 +
     share/php-build/definitions/5.3.20      |   1 +
     share/php-build/definitions/5.3.21      |   1 +
     share/php-build/definitions/5.3.22      |   1 +
     share/php-build/definitions/5.3.23      |   1 +
     share/php-build/definitions/5.3.24      |   1 +
     share/php-build/definitions/5.3.25      |   1 +
     share/php-build/definitions/5.3.26      |   1 +
     share/php-build/definitions/5.3.27      |   1 +
     share/php-build/definitions/5.3.28      |   1 +
     share/php-build/definitions/5.3.29      |   1 +
     share/php-build/definitions/5.3.3       |   1 +
     share/php-build/definitions/5.3.6       |   1 +
     share/php-build/definitions/5.3.8       |   1 +
     share/php-build/definitions/5.3.9       |   1 +
     share/php-build/definitions/5.4.0       |   1 +
     share/php-build/definitions/5.4.1       |   1 +
     share/php-build/definitions/5.4.10      |   1 +
     share/php-build/definitions/5.4.11      |   1 +
     share/php-build/definitions/5.4.12      |   1 +
     share/php-build/definitions/5.4.13      |   1 +
     share/php-build/definitions/5.4.14      |   1 +
     share/php-build/definitions/5.4.15      |   1 +
     share/php-build/definitions/5.4.16      |   1 +
     share/php-build/definitions/5.4.17      |   1 +
     share/php-build/definitions/5.4.18      |   1 +
     share/php-build/definitions/5.4.19      |   1 +
     share/php-build/definitions/5.4.2       |   1 +
     share/php-build/definitions/5.4.20      |   1 +
     share/php-build/definitions/5.4.21      |   1 +
     share/php-build/definitions/5.4.22      |   1 +
     share/php-build/definitions/5.4.23      |   1 +
     share/php-build/definitions/5.4.24      |   1 +
     share/php-build/definitions/5.4.25      |   1 +
     share/php-build/definitions/5.4.26      |   1 +
     share/php-build/definitions/5.4.27      |   1 +
     share/php-build/definitions/5.4.28      |   1 +
     share/php-build/definitions/5.4.29      |   1 +
     share/php-build/definitions/5.4.3       |   1 +
     share/php-build/definitions/5.4.30      |   1 +
     share/php-build/definitions/5.4.31      |   1 +
     share/php-build/definitions/5.4.32      |   1 +
     share/php-build/definitions/5.4.33      |   1 +
     share/php-build/definitions/5.4.34      |   1 +
     share/php-build/definitions/5.4.35      |   1 +
     share/php-build/definitions/5.4.36      |   1 +
     share/php-build/definitions/5.4.37      |   1 +
     share/php-build/definitions/5.4.38      |   1 +
     share/php-build/definitions/5.4.39      |   1 +
     share/php-build/definitions/5.4.4       |   1 +
     share/php-build/definitions/5.4.40      |   1 +
     share/php-build/definitions/5.4.41      |   1 +
     share/php-build/definitions/5.4.42      |   1 +
     share/php-build/definitions/5.4.43      |   1 +
     share/php-build/definitions/5.4.44      |   1 +
     share/php-build/definitions/5.4.45      |   1 +
     share/php-build/definitions/5.4.5       |   1 +
     share/php-build/definitions/5.4.6       |   1 +
     share/php-build/definitions/5.4.7       |   1 +
     share/php-build/definitions/5.4.8       |   1 +
     share/php-build/definitions/5.4.9       |   1 +
     share/php-build/definitions/7.1.0       |   2 +-
     share/php-build/definitions/7.1.1       |   2 +-
     share/php-build/definitions/7.1.10      |   2 +-
     share/php-build/definitions/7.1.11      |   2 +-
     share/php-build/definitions/7.1.12      |   2 +-
     share/php-build/definitions/7.1.13      |   2 +-
     share/php-build/definitions/7.1.14      |   2 +-
     share/php-build/definitions/7.1.15      |   2 +-
     share/php-build/definitions/7.1.16      |   2 +-
     share/php-build/definitions/7.1.17      |   2 +-
     share/php-build/definitions/7.1.18      |   2 +-
     share/php-build/definitions/7.1.19      |   2 +-
     share/php-build/definitions/7.1.2       |   2 +-
     share/php-build/definitions/7.1.20      |   2 +-
     share/php-build/definitions/7.1.21      |   2 +-
     share/php-build/definitions/7.1.22      |   2 +-
     share/php-build/definitions/7.1.23      |   2 +-
     share/php-build/definitions/7.1.24      |   2 +-
     share/php-build/definitions/7.1.25      |   2 +-
     share/php-build/definitions/7.1.26      |   2 +-
     share/php-build/definitions/7.1.27      |   2 +-
     share/php-build/definitions/7.1.28      |   2 +-
     share/php-build/definitions/7.1.29      |   2 +-
     share/php-build/definitions/7.1.3       |   2 +-
     share/php-build/definitions/7.1.30      |   2 +-
     share/php-build/definitions/7.1.31      |   2 +-
     share/php-build/definitions/7.1.32      |   2 +-
     share/php-build/definitions/7.1.33      |   2 +-
     share/php-build/definitions/7.1.4       |   2 +-
     share/php-build/definitions/7.1.5       |   2 +-
     share/php-build/definitions/7.1.6       |   2 +-
     share/php-build/definitions/7.1.7       |   2 +-
     share/php-build/definitions/7.1.8       |   2 +-
     share/php-build/definitions/7.1.9       |   2 +-
     share/php-build/definitions/7.2.0       |   2 +-
     share/php-build/definitions/7.2.1       |   2 +-
     share/php-build/definitions/7.2.10      |   2 +-
     share/php-build/definitions/7.2.11      |   2 +-
     share/php-build/definitions/7.2.12      |   2 +-
     share/php-build/definitions/7.2.13      |   2 +-
     share/php-build/definitions/7.2.14      |   2 +-
     share/php-build/definitions/7.2.15      |   2 +-
     share/php-build/definitions/7.2.16      |   2 +-
     share/php-build/definitions/7.2.17      |   2 +-
     share/php-build/definitions/7.2.18      |   2 +-
     share/php-build/definitions/7.2.19      |   2 +-
     share/php-build/definitions/7.2.2       |   2 +-
     share/php-build/definitions/7.2.20      |   2 +-
     share/php-build/definitions/7.2.21      |   2 +-
     share/php-build/definitions/7.2.22      |   2 +-
     share/php-build/definitions/7.2.23      |   2 +-
     share/php-build/definitions/7.2.24      |   2 +-
     share/php-build/definitions/7.2.25      |   2 +-
     share/php-build/definitions/7.2.26      |   2 +-
     share/php-build/definitions/7.2.27      |   2 +-
     share/php-build/definitions/7.2.28      |   2 +-
     share/php-build/definitions/7.2.29      |   2 +-
     share/php-build/definitions/7.2.3       |   2 +-
     share/php-build/definitions/7.2.30      |   2 +-
     share/php-build/definitions/7.2.31      |   2 +-
     share/php-build/definitions/7.2.32      |   2 +-
     share/php-build/definitions/7.2.33      |   2 +-
     share/php-build/definitions/7.2.34      |   9 +++++++++
     share/php-build/definitions/7.2.4       |   2 +-
     share/php-build/definitions/7.2.5       |   2 +-
     share/php-build/definitions/7.2.6       |   2 +-
     share/php-build/definitions/7.2.7       |   2 +-
     share/php-build/definitions/7.2.8       |   2 +-
     share/php-build/definitions/7.2.9       |   2 +-
     share/php-build/definitions/7.2snapshot |   2 +-
     share/php-build/definitions/7.3.0       |   2 +-
     share/php-build/definitions/7.3.1       |   2 +-
     share/php-build/definitions/7.3.10      |   2 +-
     share/php-build/definitions/7.3.11      |   2 +-
     share/php-build/definitions/7.3.12      |   2 +-
     share/php-build/definitions/7.3.13      |   2 +-
     share/php-build/definitions/7.3.14      |   2 +-
     share/php-build/definitions/7.3.15      |   2 +-
     share/php-build/definitions/7.3.16      |   2 +-
     share/php-build/definitions/7.3.17      |   2 +-
     share/php-build/definitions/7.3.18      |   2 +-
     share/php-build/definitions/7.3.19      |   2 +-
     share/php-build/definitions/7.3.2       |   2 +-
     share/php-build/definitions/7.3.20      |   2 +-
     share/php-build/definitions/7.3.21      |   2 +-
     share/php-build/definitions/7.3.22      |   9 +++++++++
     share/php-build/definitions/7.3.23      |   9 +++++++++
     share/php-build/definitions/7.3.24      |   9 +++++++++
     share/php-build/definitions/7.3.25      |   9 +++++++++
     share/php-build/definitions/7.3.3       |   2 +-
     share/php-build/definitions/7.3.4       |   2 +-
     share/php-build/definitions/7.3.5       |   2 +-
     share/php-build/definitions/7.3.6       |   2 +-
     share/php-build/definitions/7.3.7       |   2 +-
     share/php-build/definitions/7.3.8       |   2 +-
     share/php-build/definitions/7.3.9       |   2 +-
     share/php-build/definitions/7.3snapshot |   2 +-
     share/php-build/definitions/7.4.0       |   2 +-
     share/php-build/definitions/7.4.1       |   2 +-
     share/php-build/definitions/7.4.10      |   7 +++++++
     share/php-build/definitions/7.4.11      |   7 +++++++
     share/php-build/definitions/7.4.12      |   7 +++++++
     share/php-build/definitions/7.4.13      |   7 +++++++
     share/php-build/definitions/7.4.2       |   2 +-
     share/php-build/definitions/7.4.3       |   2 +-
     share/php-build/definitions/7.4.4       |   2 +-
     share/php-build/definitions/7.4.5       |   2 +-
     share/php-build/definitions/7.4.6       |   2 +-
     share/php-build/definitions/7.4.7       |   2 +-
     share/php-build/definitions/7.4.8       |   2 +-
     share/php-build/definitions/7.4.9       |   2 +-
     share/php-build/definitions/7.4snapshot |   2 +-
     share/php-build/definitions/8.0.0       |  10 +++++++++
     share/php-build/definitions/8.0snapshot |  10 +++++++++
     share/php-build/definitions/8.1snapshot |  10 +++++++++
     share/php-build/plugins.d/composer.sh   |   2 +-
     tests/extensions.bats                   |   3 ++-
     196 files changed, 621 insertions(+), 212 deletions(-)
     create mode 100644 .github/workflows/ci.yml
     create mode 100755 install-dependencies.sh
     create mode 100644 share/php-build/definitions/7.2.34
     create mode 100644 share/php-build/definitions/7.3.22
     create mode 100644 share/php-build/definitions/7.3.23
     create mode 100644 share/php-build/definitions/7.3.24
     create mode 100644 share/php-build/definitions/7.3.25
     create mode 100644 share/php-build/definitions/7.4.10
     create mode 100644 share/php-build/definitions/7.4.11
     create mode 100644 share/php-build/definitions/7.4.12
     create mode 100644 share/php-build/definitions/7.4.13
     create mode 100644 share/php-build/definitions/8.0.0
     create mode 100644 share/php-build/definitions/8.0snapshot
     create mode 100644 share/php-build/definitions/8.1snapshot
    
    ~    
    ❯ phpenv install -l | tail
      7.4.4
      7.4.5
      7.4.6
      7.4.7
      7.4.8
      7.4.9
      7.4snapshot
      8.0.0
      8.0snapshot
      8.1snapshot
    
    ~
    ❯    
    
  2. phpenv install 8.0.0 (なんと 10 分ほどで一発成功。コンソール出力も大して長くない)
    
    ❯ phpenv install 8.0.0
    [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-production gets used as php.ini
    [Info]: Building 8.0.0 into /Users/sogaoh/.anyenv/envs/phpenv/versions/8.0.0
    [Downloading]: https://secure.php.net/distributions/php-8.0.0.tar.bz2
    [Preparing]: /var/tmp/php-build/source/8.0.0
    [Compiling]: /var/tmp/php-build/source/8.0.0
    [xdebug]: Installing version 3.0.1
    [Downloading]: http://xdebug.org/files/xdebug-3.0.1.tgz
    [xdebug]: Compiling xdebug in /var/tmp/php-build/source/xdebug-3.0.1
    [xdebug]: Installing xdebug configuration in /Users/sogaoh/.anyenv/envs/phpenv/versions/8.0.0/etc/conf.d/xdebug.ini
    [xdebug]: Cleaning up.
    Makefile:245: warning: overriding commands for target `test'
    Makefile:132: warning: ignoring old commands 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.0.0.20201224005617.log or rebuild with '--verbose' option
    [Success]: Built 8.0.0 successfully.
    
    ~ 10m 16s
    
    ~
    ❯ phpenv global 8.0.0
    8.0.0
    
    ~
    ❯ php -v
    PHP 8.0.0 (cli) (built: Dec 24 2020 01:04:55) ( NTS DEBUG )
    Copyright (c) The PHP Group
    Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
        with Zend OPcache v8.0.0, Copyright (c), by Zend Technologies
        with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans
    
    ~
    ❯  
    

ちょっとベンチマーク

すんなりビルドできたので、「これで書ける...」と思い安堵したのですが、これだけだとちょっともの足りないかなと思って PHP 8 のパワーを軽く体感しました。
テキトーに探して拾ったベンチマークプログラムを少し改変して、インストールした素のまま 8.0.0 と 7.4.9 で走らせてみた結果がこちら↓です。

PHP 8.0.0 [平均16秒くらい]


PHP 7.4.9 [平均19秒くらい]


プログラムはこちら。
https://github.com/sogaoh/php_benchmark

3秒差が即出るのはなかなかのパワーかな、という気がします。
(すぐに目に見える結果が出てヨカッタ。。)

なお、7.0.0 や 5.6.39 とも比較できれば、と思ったのですが、この環境では共に BUILD ERROR となってそれはできませんでした。

5.6.39・7.0.0 ビルド時のエラー
  • 5.6.39
・・・
[Preparing]: /var/tmp/php-build/source/5.6.39

-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: WARNING: This bison version is not supported for regeneration of the Zend/PHP parsers (found: 2.3, min: 204, excluded: 3.0).
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
configure: error: Please reinstall the libcurl distribution -
    easy.h should be in <curl-dir>/include/curl/
-----------------------------------------

The full Log is available at '/tmp/php-build.5.6.39.20201224011812.log'.
[Warn]: Aborting build.

~ 1m 58s
  • 7.0.0
・・・
[Preparing]: /var/tmp/php-build/source/7.0.0

-----------------
|  BUILD ERROR  |
-----------------

Here are the last 10 lines from the log:

-----------------------------------------
configure: WARNING: This bison version is not supported for regeneration of the Zend/PHP parsers (found: 2.3, min: 204, excluded: ).
configure: WARNING: You will need re2c 0.13.4 or later if you want to regenerate PHP parsers.
configure: error: Please reinstall the libcurl distribution -
    easy.h should be in <curl-dir>/include/curl/
-----------------------------------------

The full Log is available at '/tmp/php-build.7.0.0.20201224012356.log'.
[Warn]: Aborting build.

~ 1m 29s

最後にひとこと、ライトに試せるっていいですね。そこまでが大変だったりしますが。
それでは、良いお年を。

脚注
  1. SNSアカウントが分からなかったので、Qiita のアカウントへのリンクにしています ↩︎

  2. https://twitter.com/sogaoh/status/1342115499203674113 ↩︎

  3. https://twitter.com/sogaoh/status/1324721873834307587 ↩︎

Discussion