背景
新しいマシンを導入するたびにセットアップに時間をかけるのは大変です。このため、私の場合は、以下のように bootstrap.sh コマンドを実行するだけで環境構築ができるようにしています。
bash -c "$(curl -L https://bitbucket.org/hkob/dotfiles/raw/HEAD/bootstrap.sh)"
今回、M1 マシンが入ってきて、このままではこのスクリプトが利用できません。そこで、M1 MacBook Air をセッティングしながら、dotfiles のリポジトリも綺麗にしていこうと思います。この記事は後から逐次修正していきます。(12/17追記) 実際に実行したところ、かなりの修正がありました。 bootstrap.sh の実行と修正 - M1 MacBook Air インストール覚書(12) - hkob’s blogでインストール記録を書いています。こちらも参照してください。
bootstrap.sh における機種判定の導入
まだ、M1 MacBook Air が来ないので、ネットからわかる情報で判断しています。とりあえず uname -m
でアーキテクチャが取得できるようなのですが、Rosetta2 で動作しているターミナルでは、x86_64
が帰ってきてしまうようです。そこで、uname -m
の結果とarch -arm64 uname -m
の結果を使うことで、Rosetta2 上で実行されたらエラーを出すようにしてみようと思います。Intel Mac の場合には、arm64 アーキテクチャがないので「x86_64-」となります。ネイティブターミナルでは、「arm64-arm64」という感じになります。Rosetta2 の場合だけ「x86_64-arm64」という形になるので、これを判定すれば Rosetta2 の場合だけ例外処理ができると考えています。また、スクリプトの中で M1 かどうかを判断するフラグとして、is_arm という関数を実装しておきます(下の方で使います)。
ここまでを踏まえて前半部分はこんな感じになりました。Intel Mac でこの部分が何もなく通過していることを確認しました。M1 Air が届いたらうまくいくか確認してみます。
#!/usr/bin/env bash # エラーがあったらそこで即終了、設定していない変数を使ったらエラーにする set -eu # is_arm という関数を用意しておく。毎回 uname -m を実行するのは莫迦らしいので、UNAME 環境変数で判断 is_arm() { test "$UNAME" == "arm64"; } # アーキテクチャ名は UNAME に入れておく UNAME=`uname -m` # dotfiles の場所を設定 DOTPATH=$HOME/dotfiles # Rosetta2 でターミナルを動かしている時には強制終了させる if [ "$UNAME-$(arch -arm64 uname -m)" == "x86_64-arm64" ]; then echo "This script can not exec in Rosetta2 terminal" exit 1 fi
(12/17、arm64e という情報が間違っていたので、arm64 に修正)
defaults 系の設定
一回しかやらないことなので、いつも検索しながら設定していました。どうせ一回だけやるならここで設定してしまうことにします。 思いついたものを追記していきます。一つはスクリーンショットの影を外す設定です。 授業資料でスクリーンショットを多用するので、全てのマシンでいつも設定していました。
# スクリーンショットに影をつけないようにする defaults write com.apple.screencapture disable-shadow -boolean true killall SystemUIServer
コマンドラインツールの自動インストールおよび Rosetta2 のインストール
これまでコマンドラインツールは事前インストールしていたのですが、これも組み入れてしまおうということで、git コマンドの有無でチェックすることにしました。git がなければ、コマンドラインツールをインストールします。インストールを待つことはできないので、再度実行してもらうように促します。M1 Mac の場合には、Rosetta2 も必要なのでここで一緒にインストールしてしまうことにします。これが同時に実行できるかは、実際にマシンが来てみないとわかりません。
# git が入っていなければ、コマンドラインツールをインストール if ! command -v git > /dev/null 2>&1; then echo "Installing Command line tools ..." xcode-select --install # その場合、M1 Mac では Rosetta2 もインストールされていないと思われるので、こちらもインストール if is_arm; then # ソフトウェアアップデートで Rosetta2 をインストール。面倒なのでライセンス確認クリックをスキップ echo "Installing Rosetta2 ..." /usr/sbin/softwareupdate --install-rosetta --agree-to-license fi echo "Plaese exec ./bootstrap.sh again in $DOTPATH after installing command-line-tools and Rosetta2(M1 Mac only)." exit 1 fi
リポジトリアップデートの限定実行
これまでリポジトリは強制的にリポジトリのものにアップデートするようにしていました。ただ、テストしていてファイルを書き換えている時に git stash されて泣いたことがたくさんあったので、アップデート処理は引数を付けた時のみ実行するようにしました。アップデートしたい時は./bootstrap.sh update
とすることで内部を綺麗にした上で、リポジトリを最新版に更新します。
# このフォルダの取り扱い if [ ! -d "$DOTPATH" ]; then # 初回実行時はリポジトリがないので、clone してくる echo "Cloning dotfiles.git ..." git clone https://hkob@bitbucket.org/hkob/dotfiles.git "$DOTPATH" else # すでにフォルダがある時はそのことを表示 echo "$DOTPATH already downloaded." # 引数に update を付けた場合には、内部をきれいにして pull してくる if [ "X$*" == "Xupdate" ]; then # 内部で書き換えたものは廃棄して、リポジトリの最新版に差し替える echo "Update dotfiles.git ..." cd "$DOTPATH" git stash git checkout master git pull origin master echo fi fi
dotfiles の展開
これまで、scripts/deploy.sh に分離していましたが、見通しが悪いのでここに列記することにしました。インストールなどで参照する可能性があるので、XDG_CONFIG_HOME は bootstrap.sh 内にも定義していたようです(すっかり忘れていました)。XDG_CONFIG_HOME についてはArchWiki の XDG Base Directoryに詳しく書いてあるようです。
# ここにある dotfiles をホームに展開 (.git, .DS_Store は除外。他に除外するものが増えたらここに追記) echo "Deploying dotfiles ..." for file in .??*; do [[ "$file" = ".git" ]] && continue [[ "$file" = ".DS_Store" ]] && continue ln -fvns "$DOTPATH/$file" "$HOME/$file" done # どのくらいのアプリが使うかわからないが、XDG_CONFIG_HOME の環境変数は定義しておく # [[ -z $XDG_CONFIG_HOME ]] && XDG_CONFIG_HOME=$HOME/.config # mkdir -p "$XDG_CONFIG_HOME" # echo
(12/17追記) XDG_CONFIG_HOME はデフォルトで $HOME/.config になるので、わざわざ設定する必要はないとのことでした。この部分は削除しました。
homebrew システムのインストール
Homebrew は Intel Mac と Rosetta2 環境のものは /usr/local/bin にインストールされます。Homebrew 本家が紹介しているように M1 native のものは、/opt/homebrew に別途インストールすることにします。今後、基本的にはネイティブ版でインストールし、インストールできなかった場合には Rosetta2 版でインストールすることにします。ここで毎回パスを書くのは面倒なので、Rosetta2 版の brew は brew_x86 という名前で実行できるようにしておきます。このあたりがちゃんと動くかどうかは、Air が届いてから確認します。
# install homebrew if ! command -v brew > /dev/null 2>&1; then # Install homebrew in Intel Mac or M1 Mac on Rosetta2 echo "Installing homebrew in /usr/local for Intel or Rosetta2 ..." arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" echo # M1 Mac では /opt/homebrew にネイティブ版をインストール if is_arm; then echo "Installing homebrew in /opt/homebrew for Arm ..." cd /opt sudo mkdir homebrew sudo chown $USER:admin homebrew curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew # M1 の場合には、Rosetta2 版の brew を brew_x86 という名前で実行できるようにしておく cd /usr/local/bin ln -s /usr/local/Homebrew/bin brew_x86 # この順番でいくと、PATH は 「/opt/homebrew/bin:/usr/local/bin:それ以外」になることを期待している。これは実行してみないとわからない fi fi
(12/17追記: brew_x86 のリンクはオリジナルの /usr/local/Homebrew/bin に張らないと動かなかったため修正しました)
Homebrew 自体のインストール
実際のアプリは brew bundle
で一括インストールします。マシンごとにインストールできるものが異なるので以下のフォルダに Brewfile を分けて記述することにしました。
- arm_brew/Brewfile: M1 native のアプリ
- rosetta2_brew/Brewfile: Rosetta2 でしか動作しないアプリ
- intel_brew/Brewfile: Intel Mac のアプリ
まず、現在の Brewfile を intel_brew/Brewfile に移動します。M1 Mac の方ではアプリの検証をした上で arm_brew/Brewfile または rosetta2_brew/Brewfile に振り分けていきます。App Store のアプリは mas、GUI アプリは brew cask でインストールしますが、これは arm_brew/Brewfile の方に記載しておけば良いと思います。これらの振り分けについては、この記事で説明していきます。
# homebrew and cask if is_arm; then echo "brew bundle in Arm native ..." cd arm_brew brew bundle echo "brew bundle in Rosetta2 ..." cd ../rosetta2_brew brew bundle cd .. else echo "brew bundle in Intel ..." cd intel_brew brew bundle cd .. fi echo
(12/17追記) コメントが逆になっていたので修正しました。
config の復元
mackup による config は機種依存しないと思うので、そのままにしておきます。
# config の共有の復元 echo "Restoring config files by mackup ..." mackup restore echo
MacTeX の環境設定
これまで頑張ってヒラギノフォントを PDF に埋め込むように設定していました。しかし、TeX Live 2020 でデフォルトで設定される「原の味フォント」がかなりよくなっているので、無理しないことにしました。このため、TeX Live をアップデートだけの処理になっています。
# MacTeX (TeX Live) のアップデート echo "Updating TeX Live library ..." TLMGR_REPOSITORY=http://ftp.jaist.ac.jp/pub/CTAN/systems/texlive/tlnet sudo tlmgr option repository $TLMGR_REPOSITORY sudo tlmgr update --self --all --no-persistent-download
Ruby のインストール
Ruby は rbenv で最新版をインストールします。インストールされていなければ、インストールするようになっています。この時、openssl は homebrew でインストールしたものを使うようにしています。
# Ruby のアップデート RBENV_VERSION=2.7.2 RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)" now_rbenv=$(rbenv version | awk '{print $1}') if [ "X${now_rbenv}" != "X${RBENV_VERSION}" ]; then echo "Installing ruby ..." rbenv install $RBENV_VERSION rbenv global $RBENV_VERSION fi
終了
最後に Bootstrapping DONE が表示されておしまいです。
echo "Bootstrapping DONE!"
さて、これが M1 Mac で動作するかは、届いてからのお楽しみ。
次の記事: Big Sur の環境設定(1段目) - M1 MacBook Air インストール覚書(4) - hkob’s blog 前の記事: 既存環境の環境変更 - M1 MacBook Air インストール覚書(2) - hkob’s blog