fvm flutter doctorを実行した際に、pathに関する警告が出て困った経験があったので、その解決策を示す。
警告内容は以下の通り。
|
|
上記のエラーは、システムの PATH に設定されている dart コマンドが、現在の Flutter SDK 内に存在しないために発生している。
fvm flutter doctor を実行した際に、dart コマンドのパスが適切に設定されていない場合に警告が表示される。これは FVM の問題ではなく、Flutter がシステムの dart コマンドのパスと、FVM で選択された Flutter SDK 内の dart コマンドのパスを比較しているため生じるものである。
fvm flutter doctor と flutter doctor は、基本的に同じ操作を実行するため、どちらのコマンドを使っても、選択された Flutter バージョンでコマンドが実行される。
そのため、警告を表示させたくない場合は、flutter doctor を使って問題ない。
なぜ警告が出るのか?
警告が表示される理由は、システムの PATH で見つかる dart コマンドが、FVM で選択された Flutter SDK 内の dart コマンドではなく、別の場所にあるため。これが fvm flutter doctor で警告が表示される原因である。
fvm flutter doctor を実行した際の、警告の流れは以下の通り。
- FVM は選択された Flutter バージョン(この場合は
/Users/ka_mori/fvm/versions/3.7.8)を使ってflutter doctorコマンドを実行。 flutter doctorは、PATHに設定されたdartコマンドの場所をチェックする。この場合、/usr/local/Cellar/dart/2.19.5/libexec/bin/dartが最初に見つかる。- 次に、
flutter doctorは、選択された Flutter SDK 内のdartコマンドの場所をチェックする。この場合、/Users/ka_mori/fvm/versions/3.7.8/bin/dart。 flutter doctorは、2 と 3 で見つかったdartコマンドの場所が異なることに気づき、警告を表示する。
しかし、実際には fvm を使って選択された Flutter バージョンを実行する際、PATH に設定された $HOME/fvm/default/bin が使用されている。これは、/Users/ka_mori/fvm/default -> /Users/ka_mori/fvm/versions/3.7.8 へのシンボリックリンクである。したがって、警告は無視しても問題ない。
/usr/local/Cellar/dart/2.19.5/libexec/bin/dart この PATH はどこで設定した?
/usr/local/Cellar/dart/2.19.5/libexec/bin/dart は、Homebrew 経由でインストールされた Dart のパスである。恐らく以前に Homebrew で Dart をインストールしたことがあるか、何らかの理由でこのパスが設定された可能性がある。
brew list で確認できる。
ただし、警告を完全に消す方法として、Homebrew でインストールされた Dart をアンインストールすることができる。
$ brew uninstall dart
Homebrew でインストールしたパッケージは、/usr/local/bin や /usr/local/opt ディレクトリに格納されており、macOS はデフォルトで /usr/local/bin がシステムの PATH に含まれている
つまり、homebrew で入れたものは自動的に path に設定される。 これにより、ターミナルでそのパッケージのコマンドをすぐに実行できるようになる。
/usr/local/Cellar/dart/2.19.5/libexec/bin/dart は、/usr/local/binや/usr/local/opt にも入ってなくないか?
/usr/local/Cellar/dart/2.19.5/libexec/bin/dart は、実際には /usr/local/bin や /usr/local/opt には含まれていない。ただし、Homebrew でインストールされた Dart は、通常 /usr/local/Cellar/dart/<version>/libexec/bin にインストールされる。
Homebrew はインストール後、シンボリックリンクを作成して、実行可能ファイルを /usr/local/bin にリンクする。このため、Dart コマンドを実行すると、システムの PATH から /usr/local/bin にあるシンボリックリンクを経由して、最終的に /usr/local/Cellar/dart/<version>/libexec/bin/dart が実行される。
システムの PATH には /usr/local/bin が含まれているため、間接的に Homebrew でインストールされた Dart が PATH に設定されているといえる。
なぜ /Users/ka_mori/fvm/default/bin を先に PATH 設定しているのに、/usr/local/bin の Dart の方が先に見つかるのか?
PATHには、/Users/ka_mori/fvm/default/binが最初に設定されている。which flutterおよびwhich dartの結果は、FVM で選択された Flutter SDK 内のflutterおよびdartを示す。- しかし、
fvm flutter doctorを実行すると、警告が表示される。
この状況から、fvm が flutter コマンドをラップしていることが影響していると考えられる。fvm が flutter コマンドをラップしているため、flutter コマンドが内部で dart コマンドを呼び出す際に、システムの PATH が正しく解決されず、/usr/local/bin の dart が先に見つかっている可能性がある。
dart を uninstall したが、警告が消えない
似たような別の警告が出た。
|
|
警告によると、Dart が /opt/homebrew/Cellar/dart/2.17.5/libexec/bin/dart にも存在していることがわかる。
なので、/opt/homebrew/Cellar/dart/2.17.5/libexec/bin/dart が残っている場合は、そのディレクトリを削除する。
これで fvm flutter doctor で警告が出なくなる!
/usr/local/ と opt/homebrew はなんだったのか?
/opt/homebrew/ は、Apple Silicon(M1 チップ)を搭載した Mac 向けの Homebrew のインストール先である。Apple Silicon(M1)用のバイナリを提供するために、Homebrew は Intel Mac 向けの /usr/local/ とは別のディレクトリ /opt/homebrew/ にインストールされる。
Intel Mac の場合、Homebrew は /usr/local/ にインストールされることが一般的である。しかし、Apple Silicon Mac では、/opt/homebrew/ が使用されるため、同じシステム上で 2 つの異なるアーキテクチャのバイナリが存在することがある。
まとめ
警告が出ていた理由は、/opt/homebrew, /usr/local/ のどちらのディレクトリにも Dart がインストールされていたからである。ディレクトリを削除することで問題が解決したが、今後同様の問題が発生しないよう、使用しているツールのアーキテクチャには注意していきたい。