🏯

asdf+Homebrewで怠惰にPHPの環境を整える

2023/05/20に公開
1

TL;DR

  1. Homebrew で直接 PHP いれればいいよね(=ビルドに苦しむことはない!)
$ brew install php
$ brew install php@8.0
  1. まずは asdf で PHP の管理が出来るようにしよう
$ asdf plugin add php
$ mkdir ~/.asdf/installs/php
  1. asdf のディレクトリにシンボリックリンクを入れる
$ ln -s /opt/homebrew/opt/php ~/.asdf/installs/php/8.2
$ ln -s /opt/homebrew/opt/php@8.1 ~/.asdf/installs/php/8.1
  1. asdf の shims を作り直す
$ asdf reshim
  1. Happy hacking!
$ asdf list php
  8.1
  8.2
$ asdf global php 8.2
$ asdf list php
  8.1
 *8.2
$ php -v
PHP 8.2.6 (cli) (built: May 11 2023 12:51:38) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.6, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.6, Copyright (c), by Zend Technologies

前提

開発環境

  • Mac
    • macOS 13
    • Apple M1 チップ
  • fish shell
    • これは MUST

使いたい PHP のバージョン

  • 8.2
  • 8.1
    • CLIとして使えればOK。ライブラリも適当でOK。
  • 自前でビルドしたPHP
    • 拡張機能を使いたい

phpenv + Homebrew な環境

これまでこちらのスライドを参考に phpenv + Homebrew な環境を使っていました。

https://speakerdeck.com/uzulla/phpfalsebirudonitukareta-falsede-phpenv-plus-homebrew

phpenv はそのまま使っていたのですが、 anyenv + phpenv を使いたくなったのでインストールを試みました。が、出来なかった。
端的に言うと anyenv は fish と相性が悪いっぽい。

そこで anyenv + phpenv ではなく asdf を使うことに

asdf + asdf-php な環境

asdf は開発ツールのバージョン管理を出来るツール。fishもちゃんとサポートしています。

https://asdf-vm.com/

asdf-php は asdf で PHP のバージョン管理が出来るようになるためのプラグインです。

https://github.com/asdf-community/asdf-php

$ asdf plugin add php

を実行することで php のバージョン管理が出来るようになります。

asdf-php を使って php のビルド&インストールするには以下のコマンドを実行。

$ asdf install php 

が、なぜか上手くビルドが出来なかった。(ちゃんと調査していないですが、actionsが落ちていたので、コントリビュートチャンスかも)

ビルドをするだけなら Homebrew が楽なので、asdf-php の部分を Homebrew に置き換える方針に。

asdf + Homebrew な環境

https://asdf-vm.com/

asdf の仕組み

asdf では~/.asdf/shims/にバージョン管理したいコマンドと同名の実行ファイルが置かれます。
~/.asdf/shims/は asdf をインストールするとPATH変数に設定されます。

そのため、phpコマンドを実行すると~/.asdf/shims/phpが実行されます。

この実行ファイルの中身は、この様になっています。

~/.asdf/shims/php
#!/usr/bin/env bash
# asdf-plugin: php 8.1
# asdf-plugin: php 8.2
exec /opt/homebrew/opt/asdf/libexec/bin/asdf exec "php" "$@" # asdf_allow: ' asdf '

asdf を使うとphpというコマンドを実行したとき、実際にはasdf exec "php" "$@"が実行されます。

asdf execでは.tool-versionsで指定されたバージョンを、~/.asdf/installs/php/から探し出し、そのバージョンを指定します。

例えば、8.2を指定してあると、実態としては~/.asdf/installs/php/8.1/bin/phpが実行されます。

.tool-versions
php 8.2

asdf にインストール済み PHP を読み込ませる

asdf では~/.asdf/installs/php/から読み込まれることがわかりました。

という事で、~/.asdf/installs/php/に Homebrew でインストールされた PHP のディレクトリをシンボリックリンクを貼ります。

(今回は自分の Mac が Apple silicon なので、 Homebrew のインストール先は/opt/homebrew/opt/になっています)

$ ln -s /opt/homebrew/opt/php ~/.asdf/installs/php/8.2
$ ln -s /opt/homebrew/opt/php@8.1 ~/.asdf/installs/php/8.1
$ tree -L 2 installs/
installs/
└── php
    ├── 8.1 -> /opt/homebrew/opt/php@8.1
    └── 8.2 -> /opt/homebrew/opt/php

しかし、これだけでは asdf は認識してくれません。asdf の shims を作り直す作業が必要です。

$ asdf reshim

これで asdf で PHP が使えるようになります。

$ asdf list php
  8.1
  8.2

asdf + 自前ビルドな環境

Homebrew でビルドして環境をセットアップすることがメインですが、自前でビルドした PHP も使えると便利なのでその解説もします。

まずは PHP をビルドします。ビルド先はどこでもいいですが、今回は/usr/local/php/php-8.1にしました。

$ cd [php-src-dir]
$ ./buildconfig
$ YACC="/opt/homebrew/opt/bison/bin/bison" \
    PKG_CONFIG_PATH="/usr/local/opt/oniguruma/lib/pkgconfig" \
    ./configure --prefix="/usr/local/php/php-8.1" \
    --enable-cli \
    --enable-mbstring \
    --enable-debug \
    --with-iconv=(brew --prefix libiconv)
$ make
$ sudo make install
$ tree -L 2 /usr/local/php/php-8.1
/usr/local/php/php-8.1
├── bin
│   ├── phar -> phar.phar
│   ├── phar.phar
│   ├── php
│   ├── php-cgi
│   ├── php-config
│   ├── phpdbg
│   └── phpize
├── include
│   └── php
├── lib
│   └── php
├── php
│   └── man
└── var
    ├── log
    └── run

asdf + Homebrew と同様に~/.asdf/installs/php/に自前でビルドした PHP へのディレクトリをシンボリックリンクを貼ります。
今回は8.1-devという名前にしました。

$ ln -s /usr/local/php/php-8.1 ~/.asdf/installs/php/8.1-dev

reshim をすると PHP が使えるようになります。

$ asdf reshim
$ asdf list php
  8.1-dev
  8.1
  8.2

参考

https://github.com/asdf-vm/asdf

https://github.com/asdf-community/asdf-php

Discussion

kiyomizukiyomizu

定期的にクリーンインストールして構築するときに、"また" php のインストールで引っかかるのかと悩ませていたところの処方箋になりました。ありがとうございます!