今絶賛作っているファミコンのエミュはライブラリとして作って、その副産物としてファミコンソフトの逆アセンブラと CPU をステップ実行するコマンドラインツールができました。

せっかくコマンドラインツールを作ったので、Homebrew でインストールできるようにしました。その手順を残しておきたいと思います。 リポジトリはこちらにあります。

最終的には下記コマンドでインストールできるようになります。

$ brew tap takuyaohashi/SwiftNesKit https://github.com/takuyaohashi/SwiftNesKit
$ brew install SwiftNesKit

今回は0.0.3のタグを対象にします。

Formula ファイルの作成

$ brew create https://github.com/takuyaohashi/SwiftNesKit/archive/0.0.3.tar.gz

上記コマンドで Formula ファイルの雛形ができます。takuyaihashi/SwiftNesKit0.0.3の部分は自身の環境に合わせてください。GitHub の Releases のところにある tar.gz と同じリンクになっています。

コマンドが正常に成功すると/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/swiftneskit.rbに下記のようなファイルが生成されて、自動でエディタが起動します。

# Documentation: https://docs.brew.sh/Formula-Cookbook
#                http://www.rubydoc.info/github/Homebrew/brew/master/Formula
# PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!
class Swiftneskit < Formula
  desc "NES emulator written in swift"
  homepage ""
  url "https://github.com/takuyaohashi/SwiftNesKit/archive/0.0.3.tar.gz"
  sha256 "b6f661cafa4b721cdb02e661b1c7f08876b2a950c37eac8a07ed6b41dd939cdd"
  # depends_on "cmake" => :build

  def install
    # ENV.deparallelize  # if your formula fails when building in parallel
    # Remove unrecognized options if warned by configure
    system "./configure", "--disable-debug",
                          "--disable-dependency-tracking",
                          "--disable-silent-rules",
                          "--prefix=#{prefix}"
    # system "cmake", ".", *std_cmake_args
    system "make", "install" # if this fails, try separate make/make install steps
  end

  test do
    # `test do` will create, run in and delete a temporary directory.
    #
    # This test will fail and we won't accept that! For Homebrew/homebrew-core
    # this will need to be a test that verifies the functionality of the
    # software. Run the test with `brew test SwiftNesKit`. Options passed
    # to `brew install` such as `--HEAD` also need to be provided to `brew test`.
    #
    # The installed folder is not in the path, so use the entire path to any
    # executables being tested: `system "#{bin}/program", "do", "something"`.
    system "false"
  end
end

PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST!とあるようにコメントをすべて削除します。

installメソッドのところにインストールするためのコマンドを記述します。後述しますが、僕はMakefileを使ってインストールできるようにしています。 そのMakefileprefixを渡します。

このprefixにはユーザがbrew installしたときに/usr/local/Cellar/SwiftNesKit/0.0.3/が代入されて実行されます。

testの部分は使わないので削除しました。

最終的な記述はこんな感じです。

class Swiftneskit < Formula
  desc "NES emulator written in swift"
  homepage "https://github.com/takuyaohashi/SwiftNesKit"
  url "https://github.com/takuyaohashi/SwiftNesKit/archive/0.0.3.tar.gz"
  sha256 "b6f661cafa4b721cdb02e661b1c7f08876b2a950c37eac8a07ed6b41dd939cdd"

  def install
    system "make", "install", "PREFIX=#{prefix}"
  end
end

Makefile 用意

基本的には@mono0926さんの記事を参考にしました。

しかし、僕の場合は1つのリポジトリの中にコマンドラインツールが2つあったので少し改造しています。TOOL_NAMEのところにコマンドラインツール名を羅列すれば良いようになっています。

TOOL_NAME = nes-disasm nes-cpu
VERSION = 0.0.3

PREFIX?=/usr/local
INSTALL_PATH = $(PREFIX)/bin/
BUILD_PATH = $(addprefix .build/release/,$(TOOL_NAME))

.PHONY: install build test lint clean xcode

build:
	swift build --disable-sandbox -c release -Xswiftc -static-stdlib

install: build
	mkdir -p $(INSTALL_PATH)
	cp -f $(BUILD_PATH) $(INSTALL_PATH)

こちらのファイルをリポジトリのルートに配置してcommit, pushしておきます。

インストールの確認

先程変更した Formula ファイル/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/swiftneskit.rbを使ってインストールの確認を行います。

$ brew install SwiftNesKit

コマンドを打つと先程のMakefileを使ってインストールできていることを確認してください。

SwiftNesKitの場合、以下のような形でコマンドラインツールがインストールされます。先程指定したprefixに配置されてシンボリックリンクで実現されています。

/usr/local/bin/nes-disasm -> /usr/local/Cellar/swiftneskit/0.0.3/bin/nes-disasm
/usr/local/bin/nes-cpu -> /usr/local/Cellar/swiftneskit/0.0.3/bin/nes-cpu

Formula ファイルをコピー

リポジトリのルートにFormulaという名前のディレクトリを作成し、先程のファイルをコピーしてcommit, pushします。ユーザがbrew tapしたときにこのファイルが読まれます。

$ mkdir Formula
$ cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/swiftneskit.rb Formula/
$ git commit -a -m "add Formula file"
$ git push -u origin master

インストールの確認(再)

これでちゃんと GitHub からインストールできるか確認します。

まずアンインストールして、brew createコマンドで自動生成された Formula ファイルを削除します。

$ brew uninstall SwiftNesKit
$ rm /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/swiftneskit.rb

正常にアンインストールできたら、下記コマンドで GitHub からダウンロードしてインストールできることを確認します。

$ brew tap takuyaohashi/SwiftNesKit https://github.com/takuyaohashi/SwiftNesKit
$ brew install SwiftNesKit

brew tapしたときに Formula ファイルは/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/swiftneskit.rbに配置されます。brew createしたときとは異なるディレクトリに入るようですが、どっちが優先度高いのかは試していません。

エラーが出たら頑張って消していきましょう。

バージョンアップ方法

今回は0.0.3のタグを使って行いました。今後バージョンアップしていきます。その時にこの項目は更新していきたいと思います。