ひみつメモ帳を現行の macOS に対応させたい

ひみつメモ帳で使っていた OpenSSL ライブラリは、現行の macOS (Mojave) だと標準装備されなくなっている。したがって自分で openssl ライブラリをビルドして同梱する必要がある。ソースをダウンロードして自分でビルドしてもいいが、Homebrew か MacPorts を使うと楽そう。あまり考えずみんな大好き Homebrew にしてみる。

Homebrew でインストールしたライブラリとリンクしてビルドするところまでは簡単。しかしここで問題が出る。できたバイナリは openssl ライブラリを Homebrew でインストールしている環境でしか動かない。ユーザーに Homebrew で手作業で入れてもらうわけにもいかないし。バイナリがどこのライブラリを見にいくかは otool -L でわかる。

こういうときの定石としては、アプリのパッケージ内にライブラリをコピーしてそれを使うようにすればいいらしい。Xcode のビルド設定でできる。しかしコピーするだけで実行ファイルがそのライブラリを探すようになるわけではないので動かない。そこでビルド後の Run Script フェーズで install_name_tool を使ってバイナリのライブラリ参照先を書き替える。

これで .app 単体でどの環境でも起動するようになった。Parallels で作った新規インストールの macOS で確認。いまの macOS は開発、テスト用に仮想環境に2つまでコピーをインストールできることが使用許諾に含まれている。

しかしこのプロジェクトをアーカイブしてストア用に validate すると通らない。

OpenSSL の .dylib バイナリに LC_VERSION_MIN_MACOSX ロードコマンドが含まれていないのがエラーのひとつ。このライブラリは Homebrew で入れたものなので、brew install のビルド設定を変えないとだめそう。

ここでものすごく時間を費やす。

けっきょく、Homebrew では LC_VERSION_MIN_MACOSX を付けるビルドにカスタマイズすることはできないというのを発見する。Homebrew は捨てて MacPorts を使え。

MacPorts でもそのまま欲しいパッケージを入れると LC_VERSION_MIN_MACOSX は付かない。ちなみにこの確認は otool -l でできる。そこで /opt/local/etc/macports/macports.conf を編集して設定を変更する。

末尾に

macosx_deployment_target 10.12

の設定を追加。ちなみにこのオプションは文書化されていない(ファッ○)。

また、~/.bash_profile に export MACOSX_DEPLOYMENT_TARGET=10.12 を追加してみたが、これははなくても LC_VERSION_MIN_MACOSX が付いたので消した。参考にしたサイトには universal_target と macosx_sdk_version も指定するよう書いてあったが、universal_target オプションはいまの MacPorts では廃止されたのでもう存在せず、macos_sdk_version はおそらくビルドに使う SDK のバージョンなので、対象となる OS のバージョンの設定とは無関係とみて設定しなかった。

上記の作業をやったうえで、インストール時に、

sudo port install -s openssl

と -s オプション付きで導入すればよい。このオプションを付けるのは、そのままだとパッケージによってはビルド済みバイナリを取ってきて導入してしまうからで、それだともちろんビルド設定は反映されていない。ソースからちゃんとビルドするように指定するオプション。ただし当然ながら導入までの時間は長くかかる。

(2020-04-07追記) /opt/local/etc/macports/macports.conf の buildfromsource オプションを always にすると毎回 -s オプションを付けなくてもソースからビルドしてくれる。

これでアプリの validation における .dylib の問題は解決。その後 App ID が登録されてないとかカテゴリが一致してないとかあったがそれはアップルの開発者サイトで登録したり Xcode で設定を合わせたりすればよい。

アプリのサンドボックス関連の検証エラーで、.entitlements ファイルの com.apple.security.app-sandbox の値が真になってないとか言ってくることがあるが、.entitlements ファイルを見てもちゃんと設定されている。これはターゲットの設定の Capabilities にある App Sandbox 設定を on にすればよい。

アプリの登録ページで、ひみつメモ帳は暗号関係ライブラリを使ってるので、米国の輸出規制対象となるのでコンプライアンス書類を提出する必要がある。いまここ。めんどくさそう。

pip 非対応のモジュールを virtualenv で使うには(OS X 編)

Windows 編POSIX 編の続き。というかこれが本題。

これまで説明してきた方法でシステムにインストールしたパッケージやライブラリを virtualenv 環境にリダイレクトできるのだけど、このやりかたを使って OS X で wxPython を使おうとすると、以下のような奇妙なメッセージが出てうまくいかない。

This program needs access to the screen.
Please run with a Framework build of python, and only when you are
logged in on the main display of your Mac.

どうも OS X の Python は特定の場所にインストールされているバイナリでないと GUI のフレームワークなどを使うことができないらしい(適当な推測)。virtualenv は作業ディレクトリにインタプリタをコピーするのでそれではじかれるようだ。

これは困った。コピーしたインタプリタが使えないんじゃ virtualenv できないじゃないか。で、あれこれ考えたのだけど、環境変数 PYTHONHOME を設定してもとの python を実行すれば別の環境でインタプリタを起動できることに気づいた。virtualenv 環境が /path/to/venv ディレクトリにあるなら、PYTHONHOME を /path/to/venv にして /usr/bin/python を実行すれば、virtualenv と同等のカプセル化の恩恵が得られる。

そこで、activate.csh に(tcsh なんすよ……)、PYTHONHOME を設定するような記述(と、deactivate したときにそれを戻す記述)を追加してみた。それから、virtualenv が作った作業ディレクトリの python コマンドの代わりに、システムの python へのシンボリックリンクを置く。

ln -s /usr/bin/python /path/to/venv/bin/

改造した activate.csh は Gist に置きました。bash 用のスクリプトをだれか作ってあげてください。

それはさておき、こうするとそれまでの virtualenv と同様の使い勝手で開発を続けることができる。めでたい。

めでたいのだけど、virtualenv 環境を作るごとにこの作業をするのは面倒くさい。なんとか virtualenv のほうで対応してくれないものかなあ……。僕の力量ではどうしていいのかわからん。

pip 非対応のモジュールを virtualenv で使うには(POSIX 編)

Windows 編の続き。

Windows ではハードリンクとジャンクションで行ったが、Linux や OS X など、POSIX の環境であればハードリンクとシンボリックリンクで同様に対策できる。じつは Windows 編で紹介したスクリプト(redirect-package.py)は、すでに POSIX 環境ではそう処理するようになっている。

Linux ではこれで問題ない。

ところが、OS X ではこれで wxPython を使えるようにしようとすると virtualenv 環境では wx モジュールをインポートできない。次回にはこれについて書きます。

いつの間にか Safari の「ブックマーク」メニューに「ブックマークメニュー」配下のブックマークだけでなく、ブックマークのルートにあるブックマークも表示されるようになっていた(ややこしいな)。

これは Safari がほかのブラウザに歩み寄ったね。IE や Chrome などではもとからブックマーク(お気に入り)のルートからメニューバーに表示される仕様だったのに、これまで Safari はルートでなくその下の「ブックマークメニュー」配下しかメニューバーからは辿れなかった。ルート直下のブックマークはブックマーク管理画面からしか見えなかったのだ。これのせいで iCloud でブックマークを Windows PC と同期すると PC のブックマークには「Safari メニュー」という無駄な1階層がついて回っていた。それが、このいつの間にかの変更で解消されたわけだ。

互換性のためか Safari では引き続き「ブックマークメニュー」フォルダのブックマークもブックマークメニューに表示されるけど(ああややこしい)、ここにあるブックマークをぜんぶ1階層上のルートに移動させてもメニューバーから見えなくなることはない(のでそうすべし)。そうすると、iCloud 経由で同期させている iPhone や Windows PC などでもブックマークがより自然な感じでマージされるはず。

ちなみに「ブックマークメニュー」配下のブックマークをぜんぶルートに移動させたら「ブックマークメニュー」フォルダじたいが消えた!

Xmarks が iCloud と競合しておかしくなるようになって以来 Mac/Win 間のブックマーク同期は諦めてたのだけど、また同期させるようにしようかなあ。Windows に iCloud コントロールパネル入れるのがちょっと嫌だけどね。

Mountain Lion の「メール」では新規アカウントの追加時に POP / IMAP をマニュアルで選択できなくなった。アプリケーションがサーバで自分で問い合わせてその結果を使う。ところが、これで取得した結果を変更する方法がない。たとえば IMAP 対応してるのに POP と判定されると、あとから IMAP アカウントに設定を変えることはできない。

OS X もあるバージョンまではアカウント追加時に POP / IMAP は手動で選べたようだ。さすがアップルはやることが無茶だ。

では IMAP で使いたいのにどうしても POP にされてしまう場合はどうするか。いまわかっているかぎりでは、

「メールアドレスに存在しないアドレスを入れて続行する」

しかない。mshibata@example.com とか入れると「証明書が不正です」とか出て(というか example.com に証明書があんのかよ、というのがびっくりだけど、最近は IANA のサイトになってるのね)、同時にアカウント追加シートが旧来の POP / IMAP マニュアル選択式のものに切り替わる。あとは適宜情報を追加すればよし。

ご多分に漏れずなんでもかんでも Gmail でやってたのだけど、最近 old school なメール環境でまたやってみようかと思いだした。メール受信にブラウザを開かなくなって、ついふらっとニュース・サイトで時間を潰すみたいな誘惑がないのはいい。