Emacs のコードリーディングのための Carbon Emacs のビルド

Mac OS XCarbon 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 のコードを読んでみたいなぁと思います。