Unix のアプリを RubyMotion アプリに組み込んで実行させようとした時に、かなり苦労したのでメモっておく。
Unix アプリ (実行ファイル:executable) をそのまま resources フォルダに入れて、実行権限とコードサインをしても、公証化のプロセス弾かれて invalid と返ってきた。どうやらそのまま exe ファイルを組み込むと通らないらしい。そこで、色々な AI に聞くとともに試行錯誤して、最終的に公証化に成功したのが以下の方法。
方法としては、アプリケーションバンドルを作成して、それにコードサインすると公証化ができた。
まず、空のアプリケーションバンドルを作る。.bundle という拡張子を持ったフォルダを作成し、その中に Contents、またその中に MacOS というフォルダを作成する。アプリーションパッケージと同じ構造。ターミナルでプロジェクトの resources フォルダに移動して以下を実行。UNIX_APP のところは、お好みのバンドル名でいいが、Unix アプリの名前にした方がわかりやすい。
mkdir -p UNIX_APP.bundle/Contents/MacOS/
そしたら、.bundle フォルダを選んでコンテクストメニューから、パッケージの内容を表示を選んで、Contents -> MacOS フォルダに移動する。
この MacOS フォルダに Unix アプリを入れる。
次に、次の内容で Info.plist ファイルを作成し、バンドルの Contents フォルダに保存する。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.unix_app</string>
<key>CFBundleName</key>
<string>UNIX_APP</string>
<key>CFBundleExecutable</key>
<string>UNIX_APP</string>
</dict>
</plist>
CFBundleName は、アプリケーションバンドルの名前。ここでは上で UNIX_APP としたので、それを入れているが、ここはバンドルにつけた名前を入れる。その下の CFBundleExecutable は、MacOS フォルダに入れた Unix アプリの名前を入れる。ここでは、UNIX_APP としているが、これは、入れたアプリによる。
これで、アプリケーションバンドルの用意ができたので、最後にプロジェクトの Rake ファイルで、コードサインと実行ができるように権限を変更 (指定) する。
Motion::Project::App.setup do |app|
## 開発者の証明書などの登録をコードサインで使うので、バンドルの処理は、この部分の後に入れる。
app.codesign_certificate = "Developer ID Application: YOUR_INFO"
app.developer_userid = "YOUR_USER_ID"
app.developer_app_password = "APP_PASSWORD"
app.developer_team_id = "YOUR_TEAM_ID"
## バンドルを扱う部分:複数のバンドルを含める場合は、配列にしてブロックで処理するのがいいでしょう。
bundle_path = "#{app.resources_dirs[0]}/UNIX_APP.bundle" ## バンドルのパス
system "chmod +x #{bundle_path}/Contents/MacOS/#{File.basename(bundle_path,".*")}" ## 権限の設定
system "/usr/bin/codesign --force --deep --options runtime --sign \"#{app.codesign_certificate}\" \"#{bundle_path}\"" ## バンドルにコードサイン
## この先は、本当に必要かはよくわからないが、必要なようなので入れてある。
app.entitlements['com.apple.security.cs.allow-jit'] = true
app.entitlements['com.apple.security.automation.apple-events'] = true
end
これで、rake build:release でビルドして、rake notarize:wait で公証化を行えば、ちゃんと通るはず。