これは「Happiness Chain Advent Calendar 2023」の23日目の記事です。
https://adventar.org/calendars/9414/
はじめに
みなさんお世話になっているHomebrewですが、内部動作の理解を後回しにして使っている方もいるのではないでしょうか。
もちろん私もそうでしたが、先日躓いた際に基本動作から調べる機会がありました。
基本動作を理解することでエラーも解決できましたし、何よりも前よりHomebrewを気持ちよく使うことができるようになりました。
これを読んだ方が同じ効果を得られるように記事にまとめてみました。
特にbrew install
を実行してからインストールしたものを実行できるところに焦点を当てました。
内容
動作環境
- Apple M1
- macOS 14.1.2
- Homebrew 4.1.25-42-gcd8a9c0
用語
まずHomebrewで出てくる用語について簡単に触れておきます。
用語 | 原訳 | homebrew上での意味 |
---|---|---|
Homebrew | 自家製ビール | ツール名そのもの |
brew | 醸造する | コマンド |
formula | 製法 | インストール手順を書いたRubyスクリプト |
keg | 小樽 | インストールした実行ファイル置き場 |
cellar | 貯蔵庫 | kegをまとめて管理するディレクトリ |
大まかな流れ
brew install
実行時の大まかな流れは下記になります
- formulaを取得
- 取得したformulaを元にインストールした実行ファイルをkegに保存
- kegへのエイリアスを作成
- エイリアスにpathを通すことでシェルから呼び出せるようになる
以降で流れを追っていきます。
formulaを取得してインストール
以降は
$ brew install tree
の実行を例にします。
実行するとまず、インストール方法が書かれたformulaを取得しにいきます。
formulaはGitHub上に置かれており、treeの場合は下記のアドレスになります。
https://github.com/Homebrew/homebrew-core/blob/master/Formula/t/tree.rb
ちなみにインストール後はbrew cat tree
でもformulaの中身を確認できます。
class Tree < Formula
desc "Display directories as trees (with optional color/HTML output)"
homepage "http://mama.indstate.edu/users/ice/tree/"
url "http://mama.indstate.edu/users/ice/tree/src/tree-2.1.1.tgz"
sha256 "d3c3d55f403af7c76556546325aa1eca90b918cbaaf6d3ab60a49d8367ab90d5"
license "GPL-2.0-or-later"
livecheck do
url "http://mama.indstate.edu/users/ice/tree/src/"
regex(/href=.*?tree[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
def install
ENV.append "CFLAGS", "-fomit-frame-pointer"
objs = "tree.o list.o hash.o color.o file.o filter.o info.o unix.o xml.o json.o html.o strverscmp.o"
system "make", "PREFIX=#{prefix}",
"MANDIR=#{man}",
"CC=#{ENV.cc}",
"CFLAGS=#{ENV.cflags}",
"LDFLAGS=#{ENV.ldflags}",
"OBJS=#{objs}",
"install"
end
test do
system "#{bin}/tree", prefix
end
end
実際のインストール方法はコンパイル、バイナリ取得、インストールスクリプトなどがありますが、これをスクリプトで実行してくれているのでユーザーはbrew install
のコマンドを実行するだけで良いのです。
ちなみにインストール物がバイナリの場合はbottleと呼ばれます。
また、macOSのGUIアプリの場合はcask(大樽)と呼ばれます。以前はinstall時に--cask
オプションが必要でしたが、今は不要になりました。
保存場所とパスの確認
先ほどのbrew install tree
のコマンドでインストールが完了しました。
treeの実行可能ファイルやライブラリの実態はcellarの中のkegにインストールされます。
どこにあるか探してみましょう。
まずtreeがどこを示すかコマンドで確認してみます。
$ which tree
/opt/homebrew/bin/tree
ここがkegでしょうか?違います。詳細を見てみます。
$ ls -l $(which tree)
lrwxr-xr-x 1 takuzo admin 29 9 22 04:13 /opt/homebrew/bin/tree -> ../Cellar/tree/2.1.1/bin/tree
/opt/homebrew/bin/tree
はシンボリックリンクであることが分かります。
これはインストール時に作成されたものです。
そしてリンク先の/opt/homebrew/Cellar/tree/2.1.1/bin/tree
がkegでここに実行ファイルが置かれます。(実はインストール実行時のログにも書かれています)
実際に使われる際は/opt/homebrew/bin
に置かれたシンボリックリンクへアクセスされます。
homebrewをインストールした際にここへのパスが通されており、echo $PATH
で確認できます。
$ echo $PATH | grep '\/opt\/homebrew\/bin'
..前略..:/opt/homebrew/bin:..後略..
またcellarは下記のコマンドで所在を確認できます。
brew --cellar
/opt/homebrew/Cellar
以上をまとめると、brew install XXXX
を実行した際はCellarの中に実行ファイルが置かれ、コンソールからコマンドを実行したときは下記の流れで実行ファイルが呼び出されます。
- $PATH
- /opt/homebrew/bin/XXXX
- /opt/homebrew/Cellar/XXXX/X.X.X/bin/XXXX
補足:CPUによる保存場所の違い
ちなみにMacのintelコア(x86_64)では/usr/local/binに置かれていましたが、M1チップ(arm64)以降は/opt/homebrew/binに置かれるようになりました。
その他のvarやetcもintelコアではrootに置かれますがM1以降は/opt/homebrew配下へ置かれるようになりました。
古い記事を読んだ際は置き場が異なるので注意してください。
補足:リンクについて
上記で説明したようにインストールされると自動でリンクが貼られますが、手動でリンクを貼る必要がある場合があります。
openssl, node, mysqlなど複数のバージョンのkegがcellarの中に存在する場合や、マニュアルでインストールした場合です。
その場合はbrew link --force openssl@1.1
のようにするとリンクが貼られます。
(本来はコンテナやasdfなどで管理するべきですが。。。)
参考にbrew linkのコマンドヘルプも載せておきます。
brew link -h
Usage: brew link, ln [options] installed_formula [...]
Symlink all of formula's installed files into Homebrew's prefix.
This is done automatically when you install formulae but can be useful for manual installations.
おわりに
Homebrewでインストールしてから使えるようになるまでの流れを確認できました。
これで以前よりも気持ちよくbrew install
コマンドを実行できるようになったのではないでしょうか。
また、もし環境構築などでトラブルがあった時はこのことを覚えていると早く解決できるようになると思います。
参考
記事作成にあたり、下記を参考にさせていただきました!