はじめに
昨日、homebrew-cask の方は簡単にいったのですが、本家の Formula はだいぶ苦戦しました。すでにあるものをコピーして修正しても、その Formula があることをうまく認識してくれない状況が改善しませんでした。
ということで、基本に忠実にHomebrewでformulaの作成 | ottijp blogを参考に 1 から作って今までのものに似せていく形にしてみます。
(最後まで書いてからの追記: まさか Homebrew 本体まで手を入れることになるとは、この時点では思っていませんでした)
Formula の作成
昨日と同様に GitHub に作っておいた hkob/m1-beta-brew を tap しておきます。
hkob@thin ~> brew tap hkob/m1-beta-brew ==> Tapping hkob/m1-beta-brew Cloning into '/usr/local/Homebrew/Library/Taps/hkob/homebrew-m1-beta-brew'... remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), done. Tapped (29 files, 25.6KB).
記事のように Formula を作ってみようとしたのですが、--set-name は --cask の時しか設定できないと言われてできなかったので、無指定です。無指定だと、ダウンロードした tar.gz から sshfs にされてしまいました。エディタが開きますが、修正せずに終了します。
brew create --tap hkob/m1-beta-brew https://github.com/libfuse/sshfs/releases/download/sshfs-2.10/sshfs-2.10.tar.gz ==> Downloading https://github.com/libfuse/sshfs/releases/download/sshfs-2.10/sshfs-2.10.tar.gz Already downloaded: /Users/hkob/Library/Caches/Homebrew/downloads/530b903f02c905bfdb15b1859c391f8383cfaac570656f7396ed07ca0817fd93--sshfs-2.10.tar.gz Warning: Cannot verify integrity of '530b903f02c905bfdb15b1859c391f8383cfaac570656f7396ed07ca0817fd93--sshfs-2.10.tar.gz'. No checksum was provided for this resource. For your reference, the checksum is: sha256 "70845dde2d70606aa207db5edfe878e266f9c193f1956dd10ba1b7e9a3c8d101" Please run `brew audit --new sshfs` before submitting, thanks. Editing /usr/local/Homebrew/Library/Taps/hkob/homebrew-m1-beta-brew/sshfs.rb Warning: Using vim because no editor was set in the environment. This may change in the future, so we recommend setting EDITOR, or HOMEBREW_EDITOR to your preferred text editor.
ここに書いてあるように brew audit をしてみます。既存ファイルを書き換えただけだと、Error: No available formula or cask with the name
になってしまっていました。sshfs だとオリジナルのものと区別ができないので、tap 名も付けて audit してみます。
hkob@thin ~> brew audit --new hkob/m1-beta-brew/sshfs hkob/m1-beta-brew/sshfs: * 1: col 1: Please remove default template comments * 3: col 1: Please remove default template comments * 5: col 9: Description shouldn't start with an article. * 6: col 3: Formula should have a homepage. * 11: col 3: Commented-out dependency "cmake" => :build * 14: col 5: Please remove default template comments * 15: col 5: Please remove default template comments * 20: col 5: Please remove default template comments * Formula sshfs contains deprecated SPDX licenses: ["GPL-2.0"]. You may need to add `-only` or `-or-later` for GNU licenses (e.g. `GPL`, `LGPL`, `AGPL`, `GFDL`). For a list of valid licenses check: https://spdx.org/licenses/ Error: 9 problems in 1 formula detected
ちゃんと認識していました。名前を変えてみます。
mv (brew --repository)/Library/Taps/hkob/homebrew-m1-beta-brew/{sshfs,m1-beta-sshfs}.rb
名前を変えた場合には、Ruby の Class 名も修正する必要があります。
昨日は直接 vi で編集してしまいましたが、brew edit
という便利な命令があるのを忘れていました。tap されているので、tap 名は省略できます。ちゃんと認識されていますね。
brew edit m1-beta-sshfs
class 名の部分をファイル名に合わせて、Camel Case 型で記載します。「-」の次の文字が大文字になる感じです。
class M1BetaSshfs < Formula
名前が unique になったので、Formula 名だけで audit もできました。
hkob@thin ~ [1]> brew audit --new m1-beta-sshfs hkob/m1-beta-brew/m1-beta-sshfs: * 1: col 1: Please remove default template comments * 3: col 1: Please remove default template comments * 5: col 9: Description shouldn't start with an article. * 6: col 3: Formula should have a homepage. * 11: col 3: Commented-out dependency "cmake" => :build * 14: col 5: Please remove default template comments * 15: col 5: Please remove default template comments * 20: col 5: Please remove default template comments * Formula m1-beta-sshfs contains deprecated SPDX licenses: ["GPL-2.0"]. You may need to add `-only` or `-or-later` for GNU licenses (e.g. `GPL`, `LGPL`, `AGPL`, `GFDL`). For a list of valid licenses check: https://spdx.org/licenses/ Error: 9 problems in 1 formula detected
とりあえず、真似て修正したのがこんな感じです。昨日ダメだったのは、:osxfuse を Cask 名に直していたのがダメだったみたいです。:osxfuse 自体は dependency_collector.rb の中で特殊処理する形になっていました。これが macFUSE で動くのかどうかというところです。ダメなら Homebrew の本体自体にプルリクエストを送らないといけない状況ですね。だから簡単に 4.0.4 に上げていないのかもしれません。
class M1BetaSshfs < Formula desc "File system client based on SSH File Transfer Protocol" homepage "https://osxfuse.github.io/" url "https://github.com/libfuse/sshfs/releases/download/sshfs-2.10/sshfs-2.10.tar.gz" sha256 "70845dde2d70606aa207db5edfe878e266f9c193f1956dd10ba1b7e9a3c8d101" license "GPL-2.0-or-later" depends_on "autoconf" => :build depends_on "automake" => :build depends_on "libtool" => :build depends_on "pkg-config" => :build depends_on "glib" depends_on :osxfuse patch do url "https://github.com/libfuse/sshfs/commit/667cf34622e2e873db776791df275c7a582d6295.patch?full_index=1" sha256 "ab2aa697d66457bf8a3f469e89572165b58edb0771aa1e9c2070f54071fad5f6" end def install system "./configure", "--disable-dependency-tracking", "--prefix=#{prefix}" system "make", "install" end test do system "#{bin}/sshfs", "--version" end end
ということで、audit も無事スルーしました。
hkob@thin ~> brew audit --new m1-beta-sshfs
sshfs のビルド
早速ですが、brew install してみます。デバッグ確認のために、「-dv」のオプションを付けてみます。
hkob@thin ~> brew install m1-brew-sshfs -dv ==> Installing m1-beta-sshfs from hkob/m1-beta-brew /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/autoconf.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/automake.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/libtool.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pkg-config.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/glib.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/meson.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/ninja.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/python@3.9.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gdbm.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/openssl@1.1.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/readline.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/sqlite.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/xz.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/gettext.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/libffi.rb /usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FormulaLoader): loading /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/pcre.rb m1-beta-sshfs: FUSE for macOS is required for this software. OsxfuseRequirement unsatisfied! You can install the necessary cask with: brew install --cask osxfuse You can download from: https://osxfuse.github.io/ Error: An unsatisfied requirement failed this build. /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:524:in `check_requirements' /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:487:in `compute_dependencies' /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:213:in `verify_deps_exist' /usr/local/Homebrew/Library/Homebrew/formula_installer.rb:204:in `prelude' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:382:in `install_formula' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:297:in `block in install' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:295:in `each' /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:295:in `install' /usr/local/Homebrew/Library/Homebrew/brew.rb:119:in `<main>'
やはり macFUSE は osxfuse と認識してくれない問題でした。パス名が面倒なので、Library/Homebrew に移動しましょう。
cd (brew --repository)/Library/Homebrew
ここにあるdependency_collector.rb
の 185行目で作成されている OsxfuseRequirement.new(tags) を直さないとですね。
when :osxfuse then OsxfuseRequirement.new(tags)
OsxfuseRequirement を探しましょう。requirements の下にいました。
hkob@thin /u/l/H/L/Homebrew (master)> grep OsxfuseRequirement */*.rb requirements/osxfuse_requirement.rb:class OsxfuseRequirement < Requirement
requirements/osxfuse_requirement.rb
をみます。cask "osxfuse" が書かれていますね。cask 名は osxfuse のままの方が互換性が取れそうです。ここを直すわけにはいかないので、バイナリがインストールされているかを確認する部分をチェックします。extend/os/requirements/osxfuse_requirement
にありそうです。
# typed: strict # frozen_string_literal: true require "requirement" # A requirement on FUSE for macOS. # # @api private class OsxfuseRequirement < Requirement extend T::Sig cask "osxfuse" fatal true sig { returns(String) } def display_s "FUSE" end end require "extend/os/requirements/osxfuse_requirement"
extend/os/requirements/osxfuse_requirement.rb
を確認します。linuxbrew もあるので、ここで機種判断ですね。先に進みます。
# typed: strict # frozen_string_literal: true if OS.mac? require "extend/os/mac/requirements/osxfuse_requirement" elsif OS.linux? require "extend/os/linux/requirements/osxfuse_requirement" end
さらに、extend/os/mac/requirements/osxfuse_requirement.rb
をみます。/usr/local/include/osxfuse/fuse.h
をチェックしています。昨日の記事の pkgutil の結果を確認すると./usr/local/include/fuse
になっていましたね。この部分を修正すればよさそうです。
# typed: false # frozen_string_literal: true require "requirement" class OsxfuseRequirement < Requirement extend T::Sig download "https://osxfuse.github.io/" satisfy(build_env: false) { self.class.binary_osxfuse_installed? } sig { returns(T::Boolean) } def self.binary_osxfuse_installed? File.exist?("/usr/local/include/osxfuse/fuse.h") && !File.symlink?("/usr/local/include/osxfuse") end env do ENV.append_path "PKG_CONFIG_PATH", HOMEBREW_LIBRARY/"Homebrew/os/mac/pkgconfig/fuse" unless HOMEBREW_PREFIX.to_s == "/usr/local" ENV.append_path "HOMEBREW_LIBRARY_PATHS", "/usr/local/lib" ENV.append_path "HOMEBREW_INCLUDE_PATHS", "/usr/local/include/osxfuse" end end def message "FUSE for macOS is required for this software. #{super}" end end
とりあえず、修正してみました。
def self.exist_include_osxfuse? File.exist?("/usr/local/include/osxfuse/fuse.h") && !File.symlink?("/usr/local/include/osxfuse") end def self.exist_include_fuse? File.exist?("/usr/local/include/fuse/fuse.h") && !File.symlink?("/usr/local/include/fuse") end def self.binary_osxfuse_installed? exist_include_osxfuse? || exist_include_fuse? end env do ENV.append_path "PKG_CONFIG_PATH", HOMEBREW_LIBRARY/"Homebrew/os/mac/pkgconfig/fuse" unless HOMEBREW_PREFIX.to_s == "/usr/local" ENV.append_path "HOMEBREW_LIBRARY_PATHS", "/usr/local/lib" ENV.append_path "HOMEBREW_INCLUDE_PATHS", "/usr/local/include/#{self.exist_include_osxfuse? ? "osxfuse" : "fuse"}" end end
これでコンパイルが実行できるようになりました。ただし、コンパイルエラーです。/usr/local/include/fuse の下には fuse_darwin.h は存在しませんでした。
sshfs.c:18:12: fatal error: 'fuse_darwin.h' file not found # include <fuse_darwin.h>
osxfuse 3.11.2 のマシンで fuse_darwin.h を確認してみます。osxfuse_version のプロトタイプくらいしかないですね。なくてもコンパイルできそうな気がします。
/* * Copyright (c) 2006-2008 Amit Singh/Google Inc. * Copyright (c) 2011-2017 Benjamin Fleischer */ #ifdef __APPLE__ #ifndef _FUSE_DARWIN_H_ #define _FUSE_DARWIN_H_ #ifdef __cplusplus extern "C" { #endif #include <stdint.h> const char *osxfuse_version(void); #ifdef __cplusplus } #endif #endif /* _FUSE_DARWIN_H_ */ #endif /* __APPLE__ */
とりあえず、fuse_darwin.h の include 部分を外す patch を作ってみます。
cp sshfs.c sshfs.c.orig vi sshfs.c diff -u sshfs.c.orig sshfs.c > remove_include.patch
作成されたパッチはこんな感じ
--- sshfs.c.orig 2020-12-03 10:32:25.000000000 +0900 +++ sshfs.c 2020-12-03 10:32:42.000000000 +0900 @@ -14,9 +14,6 @@ #if !defined(__CYGWIN__) #include <fuse_lowlevel.h> #endif -#ifdef __APPLE__ -# include <fuse_darwin.h> -#endif #include <assert.h> #include <stdio.h> #include <stdlib.h>
今回、patch は短いので Formula の最後にヒアドキュメントで付けてしまいました。
class M1BetaSshfs < Formula desc "File system client based on SSH File Transfer Protocol" homepage "https://osxfuse.github.io/" url "https://github.com/libfuse/sshfs/releases/download/sshfs-2.10/sshfs-2.10.tar.gz" sha256 "70845dde2d70606aa207db5edfe878e266f9c193f1956dd10ba1b7e9a3c8d101" license "GPL-2.0-or-later" depends_on "autoconf" => :build depends_on "automake" => :build depends_on "libtool" => :build depends_on "pkg-config" => :build depends_on "glib" depends_on :osxfuse patch do url "https://github.com/libfuse/sshfs/commit/667cf34622e2e873db776791df275c7a582d6295.patch?full_index=1" sha256 "ab2aa697d66457bf8a3f469e89572165b58edb0771aa1e9c2070f54071fad5f6" end patch :p0, :DATA def install system "./configure", "--disable-dependency-tracking", "--prefix=#{prefix}" system "make", "install" end test do system "#{bin}/sshfs", "--version" end end __END__ --- sshfs.c.orig 2020-12-03 10:32:25.000000000 +0900 +++ sshfs.c 2020-12-03 10:32:42.000000000 +0900 @@ -14,9 +14,6 @@ #if !defined(__CYGWIN__) #include <fuse_lowlevel.h> #endif -#ifdef __APPLE__ -# include <fuse_darwin.h> -#endif #include <assert.h> #include <stdio.h> #include <stdlib.h>
これでコンパイルが通りました。試しにデバッグつけずに reinstall した結果がこちら。
hkob@thin ~> brew reinstall m1-beta-sshfs ==> Downloading https://github.com/libfuse/sshfs/commit/667cf34622e2e873db776791df275c7a582d6295.patch?full_index=1 Already downloaded: /Users/hkob/Library/Caches/Homebrew/downloads/cdcad74dd3989c7992d0df5c9d06cabde2b6d7523ddbb551712a3733e0ba4b02--667cf34622e2e873db776791df275c7a582d6295.patch ==> Downloading https://github.com/libfuse/sshfs/releases/download/sshfs-2.10/sshfs-2.10.tar.gz Already downloaded: /Users/hkob/Library/Caches/Homebrew/downloads/530b903f02c905bfdb15b1859c391f8383cfaac570656f7396ed07ca0817fd93--sshfs-2.10.tar.gz ==> Reinstalling hkob/m1-beta-brew/m1-beta-sshfs ==> Patching ==> Applying 667cf34622e2e873db776791df275c7a582d6295.patch patching file sshfs.c Hunk #1 succeeded at 3862 (offset -58 lines). ==> ./configure --prefix=/usr/local/Cellar/m1-beta-sshfs/2.10 ==> make install 🍺 /usr/local/Cellar/m1-beta-sshfs/2.10: 6 files, 138KB, built in 12 seconds
ちゃんと作れている。sshfs --version
もちゃんと出ます。
hkob@thin ~> sshfs --version SSHFS version 2.10 FUSE library version: 2.9.9 fuse: no mount point hkob@thin ~>
パッチあてとか久しぶりすぎる。Homebrew 本体の osxfuse のプルリクエストとか送るとみんな幸せになれそうな気がするんだけど、送った方がいいのかな。
次の記事: tmcit-brew tap の作成 - M1 MacBook Air インストール覚書(10) - hkob’s blog 前の記事: 野良 homebrew-cask の作成 - M1 MacBook Air インストール覚書(8) - hkob’s blog