Emacs のコードリーディングのための Carbon Emacs のビルド
Mac OS X で Carbon Emacs を自力でビルドできるかどうか試してみたところ、あっさりできました。
なぜ、Carbon Emacs を自力でビルドしたくなったのかと言うと、梅田望夫さんの例の本を読んで、Richard Stallman によって書かれた Emacs のコードを趣味で読んでみたくなったからです。
それで、コードを読むからには、まずは自力でビルドできないといけないかなと思いました。
ビルドログ
備忘録のためにビルドの際の作業ログを残しておきます。
% uname -rs Darwin 8.10.1 % cd ~/src % wget http://ftp.gnu.org/gnu/emacs/emacs-22.1.tar.gz % tar zxvf emacs-22.1.tar.gz % cd emacs-22.1 % ./configure --enable-carbon-app=/Users/ysano/carbon % make % sudo make install
正常にビルドが完了すると、以下に Carbon Emacs がインストールされました。
/Users/ysano/carbon/Emacs.app/Contents/MacOS/EmacS
規模の下調べ
Emacs のソースの量を簡単に調べてみたところ、約 36 万行。
読むのはなかなか手強そう。。。
% cd ~/src/emacs-22.1/src % find . -type f | egrep "\.(c|h)$" | xargs cat | wc -l 358500
main 関数はどこ?
今は Emacs がどのようにして立ち上がるのか興味があるので、まず main 関数を調べてみることにしました。
main 関数の場所を grep で探してみました。
main の後は、当然「(」が続くだろうと予想して grep してみたところ、よくわからないスタートアップルーチンしかヒットしませんでした。
% cd ~/src/emacs-22.1/src % grep -rn "main(" . ./ecrt0.c:89:extern void free(), (*_libc_free) (); extern int main(); ./ecrt0.c:90:std_$call void unix_$main(); ./ecrt0.c:97: unix_$main(main); /* no return */ ./regex.c:1655:/* BEWARE, the value `20' is hard-coded in emacs.c:main(). */
明らかにおかしいことに気がつきました。
そこで、GDB を使って調べてみることにしました。
main 関数に break point を打ってみました。
そうすると、emacs.c で main 関数が定義されていることがわかりました。
こういう時に GDB は便利ですね。
% gdb carbon/Emacs.app/Contents/MacOS/Emacs (gdb) b main (gdb) run [...] Breakpoint 1 at 0x778c1: file emacs.c, line 810.
実際にソースを見てみると、main と「(」の間に半角スペースがあることが入っていました。
grep で 期待していた main 関数がヒットしなかったのは、これが原因だったということがわかりました。
他の関数の定義も見てみた所、関数名と「(」の間には半角スペースが入っていました。
こういうコーディングスタイルのコードを読むのは初めてです。
% emacs emacs.c [...] /* ARGSUSED */ int main (argc, argv #ifdef VMS , envp #endif ) int argc; char **argv; #ifdef VMS char **envp; #endif { [...] static void sort_args (argc, argv) int argc; char **argv; { [...]
GNU Global を使うという手もあった
そう言えば、GNU Global の存在を忘れていました。
GNU Global でも関数が定義されている場所を手軽に検索できますが、探している関数の候補が複数あり、かつ GDB で適切な break point を打てるような場合は、やはり GDB を使うのが一番早いかと思います。
% cd ~/src/emacs-22.1/src % gtags -v % global -x main main 794 emacs.c main (argc, argv main 1002 getloadavg.c main (argc, argv) main 10523 macterm.c #undef main main 10525 macterm.c main (void) main 477 mktime.c main (argc, argv) main 58 prefix-args.c main (argc, argv) main 830 termcap.c main (argc, argv) main 331 tparam.c main (argc, argv) main 745 xrdb.c main (argc, argv)
この続きは?
また時間を作って、ゆっくり Emacs のコードを読んでみたいなぁと思います。