なにもわからない

気分で技術系の雑記を書きます

HomeBrew で Custom Build from Source する

最近ソースコードをビルドする機会が増えてきて、ホストOS上で常用するツールについては少し管理できた方がよさそうということで、HomeBrew で Build from Source を試しています。 例えば vimclientserver オプションを有効化したい、とかが brew install でできるようになります(まだできていない)。

HomeBrew は独特の世界観があってか[?] 情報が少ないからなのか少し混乱しましたが、慣れればまあ使えるんじゃないかと思います。 慣れれば自作のソフトウェアを配布する敷居が下がったり、macOS を使っている人の環境向上に寄与できていいんじゃないでしょうか。知らんけど。

Tap を作る

まずは Tap を作ります。Tap とは A Git repository of Formulae and/or commands らしいです。 Formula は *.rb になっている The package definition、つまり vim git make とかです。

HomeBrew の用語はこちら(Keg、Cellar、Cask など)。 docs.brew.sh

リポジトリの名前を考えます。tamakiii/homebrew-core は本家の homebrew/homebrew-core と競合する(本家に Pull Request を送りたいときに困る)ので tamakiii/homebrew-tap とします。

$ brew tap-new tamakiii/homebrew-tap
Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/.git/
[master (root-commit) 390ec63] Create tamakiii/tap tap
 3 files changed, 85 insertions(+)
 create mode 100644 .github/workflows/publish.yml
 create mode 100644 .github/workflows/tests.yml
 create mode 100644 README.md
==> Created tamakiii/tap
/usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap

When a pull request making changes to a formula (or formulae) becomes green
(all checks passed), then you can publish the built bottles.
To do so, label your PR as `pr-pull` and the workflow will be triggered.

作った Tap がこちら。README と Formula/ .github/workflows があるだけの簡単な構成です。 名前の homebrew- 部分は省略できるようです。

$ ls -lsa /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap
total 8
0 drwxrwxr-x   6 tamakiii  admin  192 10 28 19:23 .
0 drwxrwxr-x   4 tamakiii  admin  128 10 28 19:23 ..
0 drwxrwxr-x  12 tamakiii  admin  384 10 28 19:28 .git
0 drwxrwxr-x   3 tamakiii  admin   96 10 28 19:23 .github
0 drwxrwxr-x   3 tamakiii  admin   96 10 28 19:27 Formula
8 -rw-rw-r--   1 tamakiii  admin  254 10 28 19:23 README.md

$ brew --repo tamakiii/tap
/usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap

$ brew --repo tamakiii/homebrew-tap
/usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap

ビルドしてみる

試しに本家の vim.rb を入れてみます。

$ cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/vim.rb Formula/

コピーした中身はこちら。依存関係やインストールコマンド本体、テストなどがあり、単体の Ruby ファイルで完結して動きます。 github.com

追加した vim Formula は、<tap-name>/<formula-name> で指定できます。

$ brew info tamakiii/tap/vim
tamakiii/tap/vim: stable 8.2.1900 (bottled), HEAD
Vi 'workalike' with many additional features
https://www.vim.org/
Conflicts with:
  ex-vi (because vim and ex-vi both install bin/ex and bin/view)
  macvim (because vim and macvim both install vi* binaries)
/usr/local/Cellar/vim/8.2.1900 (1,953 files, 33.3MB) *
  Built from source on 2020-10-28 at 19:29:45
From: https://github.com/tamakiii/homebrew-tap/blob/HEAD/Formula/vim.rb
License: Vim
==> Dependencies
Required: gettext ✔, lua ✔, perl ✔, python@3.9 ✔, ruby ✔
==> Options
--HEAD
        Install HEAD version
==> Analytics
install: 83,045 (30 days), 238,945 (90 days), 873,774 (365 days)
install-on-request: 80,611 (30 days), 231,601 (90 days), 835,450 (365 days)
build-error: 0 (30 days)

ビルド出来ました。Bottle が落とせなくて怒られていますが今回は気にしなくてよさそうです。

$ brew install tamakiii/tap/vim
Updating Homebrew...
Warning: tamakiii/tap/vim 8.2.1900 is already installed and up-to-date
To reinstall 8.2.1900, run `brew reinstall vim`

$ brew reinstall tamakiii/tap/vim
==> Downloading https://homebrew.bintray.com/bottles-tap/vim-8.2.1900.catalina.bottle.tar.gz
##O=#  #
curl: (22) The requested URL returned error: 404 Not Found
Error: Failed to download resource "vim"
Download failed: https://homebrew.bintray.com/bottles-tap/vim-8.2.1900.catalina.bottle.tar.gz
Warning: Bottle installation failed: building from source.
==> Downloading https://github.com/vim/vim/archive/v8.2.1900.tar.gz
Already downloaded: /Users/tamakiii/Library/Caches/Homebrew/downloads/094d05292a53960f72fae76726aee6cb028b92fbdabc0eb56191a4308b5f8821--vim-8.2.1900.tar.gz
==> Reinstalling tamakiii/tap/vim
Warning: A newer Command Line Tools release is available.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you an update run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/more/.

==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.2.1900/share/man --enable-multibyte --with-tlib=ncurses --with-compiledby=Homebrew --enable-csco
==> make
==> make install prefix=/usr/local/Cellar/vim/8.2.1900 STRIP=/usr/bin/true
🍺  /usr/local/Cellar/vim/8.2.1900: 1,953 files, 33.3MB, built in 1 minute 27 seconds

vim Formula には Bottle がないのでこれで良いですが、設定されているものには --build-from-source をつける必要がありそうです。せいぜい数台のマシンで動かすものなので Bottle の記述は削るとよさそうです。

また、./configuremake の出力がほしいところなので --verbose をつけるとよさそうです。 --debug はちょっとうるさかったのでやめました。

$ brew reinstall --force --verbose --build-from-source tamakiii/tap/vim
rm /usr/local/bin/ex
rm /usr/local/bin/rview
rm /usr/local/bin/rvim
rm /usr/local/bin/vi
rm /usr/local/bin/view
rm /usr/local/bin/vim

...

/usr/bin/sandbox-exec -f /private/tmp/homebrew20201028-85925-14282ki.sb nice ruby -W0 -I $LOAD_PATH -- /usr/local/Homebrew/Library/Homebrew/build.rb /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/Formula/vim.rb --verbose
tar xof /Users/tamakiii/Library/Caches/Homebrew/downloads/094d05292a53960f72fae76726aee6cb028b92fbdabc0eb56191a4308b5f8821--vim-8.2.1900.tar.gz -C /private/tmp/d20201028-85926-10g8sdh
cp -pR /private/tmp/d20201028-85926-10g8sdh/vim-8.2.1900/. /private/tmp/vim-20201028-85926-1g5a3uf/vim-8.2.1900
chmod -Rf +w /private/tmp/d20201028-85926-10g8sdh
==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.2.1900/share/man --enable-multibyte --with-tlib=ncurses --with-compiledby=Homebrew --enable-cscope --enable-terminal --enable-perlinterp --enable-rubyinterp --enable-python3interp --enable-gui=no --without-x --enable-luainterp --with-lua-prefix=/usr/local/opt/lua --enable-fail-if-missing
configure: creating cache auto/config.cache
checking whether make sets $(MAKE)... yes
checking for gcc... clang
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out

...

/usr/bin/sandbox-exec -f /private/tmp/homebrew20201028-92467-f57b26.sb nice ruby -W0 -I $LOAD_PATH -- /usr/local/Homebrew/Library/Homebrew/postinstall.rb /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/Formula/vim.rb
==> Summary
🍺  /usr/local/Cellar/vim/8.2.1900: 1,953 files, 33.3MB, built in 1 minute 45 seconds

homebrew/homebrew-core の場合

homebrew/homebrew-core 自体も HomeBrew 的には Tap の扱いになっているようです。

$ tree -L 2 /usr/local/Homebrew/Library/Taps
/usr/local/Homebrew/Library/Taps
├── homebrew
│   ├── homebrew-brewdler
│   ├── homebrew-bundle
│   ├── homebrew-cask
│   ├── homebrew-cask-versions
│   ├── homebrew-core
│   └── homebrew-services
├── osx-cross
│   ├── homebrew-arm
│   └── homebrew-avr
├── qmk
│   └── homebrew-qmk
└── tamakiii
    ├── homebrew-core
    └── homebrew-tap

15 directories, 0 files

homebrew/homebrew-core にコミットしたい場合も、GitHub 上でリポジトリを Fork して tap すれば、自分用の Tap と同様に、変更・ビルド・Pull Request の作成ができそうです。

$ brew tap tamakiii/homebrew-core
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
==> Updated Casks
logos                            rotki                            springtoolsuite                  switchhosts                      wechatwebdevtools

$ brew --repo tamakiii/homebrew-core
/usr/local/Homebrew/Library/Taps/tamakiii/homebrew-core

$ ls -lsa /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-core
total 48
0 drwxrwxr-x    13 tamakiii  admin     416 10 28 16:03 .
0 drwxrwxr-x     4 tamakiii  admin     128 10 28 19:23 ..
0 drwxrwxr-x    14 tamakiii  admin     448 10 28 16:56 .git
0 drwxrwxr-x     8 tamakiii  admin     256 10 28 16:03 .github
0 drwxrwxr-x   238 tamakiii  admin    7616 10 28 16:03 Aliases
8 -rw-rw-r--     1 tamakiii  admin     884 10 28 16:03 CODEOWNERS
8 -rw-rw-r--     1 tamakiii  admin    2960 10 28 16:03 CONTRIBUTING.md
0 drwxrwxr-x  5313 tamakiii  admin  170016 10 28 18:19 Formula
8 -rw-rw-r--     1 tamakiii  admin    1334 10 28 16:03 LICENSE.txt
8 -rw-rw-r--     1 tamakiii  admin     706 10 28 16:03 README.md
0 drwxrwxr-x     4 tamakiii  admin     128 10 28 16:03 cmd
8 -rw-rw-r--     1 tamakiii  admin    3567 10 28 16:03 formula_renames.json
8 -rw-rw-r--     1 tamakiii  admin    1144 10 28 16:03 tap_migrations.json

自作のソフトウェアを配布したい場合には Formula をインタラクティブに作る機能も用意されているようです。 gabecc.me

バージョンロックの仕組みがイマイチ使いにくかったりで少し思う所もある HomeBrew ですが、今日も多くの人に使われているツールではあるはずです。 昔ほど Formula が壊れることもほぼなくなった気がしますし、相当なゲームチェンジャーが表れない限りは当面現役なんじゃないかと思います。