長年の疑問、不満が完全ではないが一気に解決しましたのでここにまとめます。xcodebuild
許さんぞ
概要
Mac は UNIX 準拠の OS で、とても便利なコマンド資源が使えて良いのですが、開発関係のコマンド実行が異様に遅い時があるという問題を使い始めて間もなく感じるようになっていました。僕の使用用途として、以下がとても不満でした。
man ascii
等の man ページが表示されるのに5秒ほどかかることがあるgcc
が実際に実行されるまでオーバーヘッドを感じることがある- Vim で Syntastic.vim というプラグインを使用して保存する際に、よく固まる
要はコマンドの実行が遅い時があり、しかしながら一度実行されてしまうと2回目以降からはしばらく高速だということです。なんだかとても中途半端な現象でググっても出てこず、色々とモヤモヤしていました。
コマンドの遅さにキレた
流石に人間我慢の限界があります。この gcc
おかしいんじゃないのかとキレてxxd -au
した結果を示します。
00002170: 0000 0040 0c00 0000 2000 5f5f 6d68 5f65 ...@.... .__mh_e
00002180: 7865 6375 7465 5f68 6561 6465 7200 5f6d xecute_header._m
00002190: 6169 6e00 5f73 6869 6d5f 6d61 726b 6572 ain._shim_marker
000021a0: 005f 7863 7365 6c65 6374 5f69 6e76 6f6b ._xcselect_invok
000021b0: 655f 7863 7275 6e00 6479 6c64 5f73 7475 e_xcrun.dyld_stu
000021c0: 625f 6269 6e64 6572 002f 4275 696c 6452 b_binder./BuildR
000021d0: 6f6f 742f 4c69 6272 6172 792f 4361 6368 oot/Library/Cach
000021e0: 6573 2f63 6f6d 2e61 7070 6c65 2e78 6273 es/com.apple.xbs
000021f0: 2f53 6f75 7263 6573 2f78 636f 6465 5f73 /Sources/xcode_s
00002200: 656c 6563 742f 7863 6f64 655f 7365 6c65 elect/xcode_sele
00002210: 6374 2d32 3334 392f 7372 632f 7368 696d ct-2349/src/shim
00002220: 732f 0074 6f6f 6c2d 7368 696d 2e63 002f s/.tool-shim.c./
00002230: 4275 696c 6452 6f6f 742f 4c69 6272 6172 BuildRoot/Librar
00002240: 792f 4361 6368 6573 2f63 6f6d 2e61 7070 y/Caches/com.app
00002250: 6c65 2e78 6273 2f42 696e 6172 6965 732f le.xbs/Binaries/
00002260: 7863 6f64 655f 7365 6c65 6374 2f69 6e73 xcode_select/ins
00002270: 7461 6c6c 2f54 656d 7043 6f6e 7465 6e74 tall/TempContent
00002280: 2f4f 626a 6563 7473 2f78 636f 6465 5f73 /Objects/xcode_s
00002290: 656c 6563 742e 6275 696c 642f 546f 6f6c elect.build/Tool
000022a0: 5368 696d 732e 6275 696c 642f 4f62 6a65 Shims.build/Obje
000022b0: 6374 732f 6763 632e 6f00 5f6d 6169 6e00 cts/gcc.o._main.
000022c0: 5f73 6869 6d5f 6d61 726b 6572 0000 0000 _shim_marker....
ムムッ!? Xcode!?!?!?`どうやらコイツが犯人のようです。
実際、Vim でシンタックスチェックを実行したら、iTerm2 のタイトルバーに
xcodebuild
xcrun
clang
という不穏なコマンド達が表示されていました。ちなみにパスは /usr/bin
です。あ、最後の clang
ですが、Mac デフォルトでは gcc
は gcc
ではなく、clang
が擬態したものになっているんです。なんだそれ。でもまあ clang
は遅さの元凶ではありません。
遅さの検証
実際に実行して見ましょう。
$ xcodebuild
なんとこの時点で 3秒のオーバーヘッド。Fxxk!
お次は xcrun
。
$ xcrun
Usage: xcrun [options] <tool name> ... arguments ...
おっと。引数が必要なようです。気を取り直して
$ xcrun gcc
ここでも4秒ほど時間がかかりました。なお、どちらも一度実行してしまえば2回目以降はサクッと実行されます。状況が再現できましたね。
Workaround
で、この2つのクソコマンドをどうやってバイパスするかですが、まず各コマンド(gcc
やらgit
やら)の所在を調べる必要があります。なんと偶然見つけました。
$ /usr/bin/gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
はい。/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
ですね。ということでこのディレクトリをパスに追加しちゃいましょう。
export PATH="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:$PATH"
これでにっくき xcodebuild
、xcrun
が亡霊のように起き上がることはありません。
また、場合によってはそれでも PATH が /usr/bin を先頭に持ってきてしまうことがあるようです。Zsh を使っている人は以下の設定をすることをおすすめします。というか、Vim で開発コマンドを実行する場合は必須です。
Zshの設定 for Vimとか
.zshrc と .zshenv
どちらもホームディレクトリに置くべき Zsh の設定ファイルですが、どうやら設定を記述すべき項目が異なっているようです。今回は PATH
について説明します。参考は以下。
最初に .zshrc
について説明しましょう。これは通常のシェルとして起動したときに読み込まれるファイルです。設定は主にこのファイルに書くと思われるのですが、実はシェルスクリプトで実行される時は読み込まれません。なので後述するように、Zsh をログインシェルとして使っていて、Vim から何らかのプログラムを実行するときには無視されるということです。
つまり Vim では上の Workaround は適用されないんです。自分は Vim でファイル保存時にシンタックスチェックが走るようにしているので、保存するたびにイライラしてしまうんですね。なので設定を示します。
.zshenvへの記述
まず皆さんが .zshrc に書いてある PATH の情報をカットして .zshenv に貼り付けます。これだけで実はいい感じに動くようになりうるのですが、実際は違います。このファイルの先頭行に次の文を書きましょう。
setopt no_global_rcs # avoid loading /etc/profile (not to execute /usr/libexec/path_helper)
説明はコメントのとおりなのですが、これを書くことで /etc/profile
が読まれなくなります。これが読まれると何が良くないかというと、/usr/libexec/path_helper
というコマンドが実行されデフォの /usr/bin
が PATH の先頭付近に記述されてしまうのです。するとさっきの xcrun
が実行されて結局状況は変わらないんですね。ちなみにこのコマンドは /etc/paths
の内容が追加されるのですが、その中身は
$ cat /etc/paths
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
なんですね。これを回避できるのが上の文なのです。
結果
各種コマンド実行時のオーバヘッドも減ったし、Vim のシンタックスチェックが爆速になりました!今の所不具合は出ていないので多分大丈夫だと思います。よかった〜〜〜〜〜〜