🍺

Apple Silicon 未対応のアプリケーションをbrew bundleでインストールしないようにする

2021/02/11に公開1

brewにはbrew bundleというサブコマンドがあり、Brewfileというファイルで必要なアプリケーションを管理することができる仕組みが備わっています。

homebrewは3.0でApple Silicon対応しましたが、まだまだアプリケーション自体がApple Siliconをサポートしていない場合があります。この記事では、チップのアーキテクチャを判断してApple Silicon未対応のアプリケーションをスキップする方法について学んでいきます。

BrewfileはRubyのDSLである

brewfileはRubyのDSLなので、Rubyのコードを書くことができます。

とすると、RubyでApple Siliconかどうかを判別できれば良いですね。その方法について検討してみます。

RubyでApple Siliconの判定をする

RUBY_PLATFORM という定数があります。これをirbで実行してみると、バイナリのビルド対象となっているアーキテクチャについて知ることができそうです。

$ irb

irb(main):001:0> RUBY_PLATFORM
=> "universal.arm64e-darwin20"

こんな感じの判別ユーティリティを作ってみます。

def is_m1?
    !RUBY_PLATFORM.index("arm64e").nil?
end

前述した通り、BrewfileはRubyのDSLなので、

brew "mas" unless is_m1?

とすることで、Apple Siliconかを判別して、スキップすることができます。せっかくなので、もう少しDSLっぽくします。

def is_m1?
    !RUBY_PLATFORM.index("arm64e").nil?
end

def brew_skip_m1(name, **args)
    if is_m1?
        puts "Skip brew #{name}"
        return
    end

    brew name, args
end

このようなユーティリティを作成して、次のように使います。

brew_skip_m1 "mas"

Rubyなので、ふつうにrequireすることもできるので、

# utils.rb
def is_m1?
    !RUBY_PLATFORM.index("arm64e").nil?
end

def brew_skip_m1(name, **args)
    if is_m1?
        puts "Skip brew #{name}"
        return
    end

    brew name, args
end

# Brewfile
require 'utils.rb'

brew_skip_m1 "mas"

このように、ファイル分割することもできます。じっさい、私のdotfilesは、そのように管理されています。

https://github.com/mactkg/dotfiles/tree/master/config/brewfile

それでは、みなさますてきなHomebrew lifeを!

おまけ: archコマンドのこと

この記事を書く中で気づいたのですが、archコマンドで返却される情報は、Apple SiliconのArmと、そのほかのArmが区別されているんですね。

$ man arch
ARCH(1)                   BSD General Commands Manual                  ARCH(1)

NAME
     arch -- print architecture type or run selected architecture of a universal binary

...


     The arch_name argument must be one of the currently supported architectures:

           i386     32-bit intel

           x86_64   64-bit intel

           x86_64h  64-bit intel (haswell)

           arm64    64-bit arm

           arm64e   64-bit arm (Apple Silicon)

CPUのアーキテクチャには詳しくないのですが、haswellも区別しているというのは意外でした。何か詳しい人がいたら教えてください。

Discussion

hmrhmr

おそらくhaswellからAVX2命令が搭載されたからではないかと思います。