2009年11月29日日曜日

Ubuntu/GNU Emacs22の起動プロセスにおけるload-pathの構築と利用

ソースを探ったり、いろいろビルドしたりして、結構わかった。
完全とまではいきませんが、現状では十分。

load-pathに限らず、Emacsの起動プロセスをいろいろ調べた。結果として、Emacsの仕組みについて多少詳しくなったのも嬉しい。


* Ubuntu/GNU Emacs22の起動プロセスにおけるload-pathの構築と利用
** src/epaths.in
- epaths.hの素。
- この中のPATH_LOADSEARCHがload-pathの素。
- GNU配布状態:
#define PATH_LOADSEARCH "/usr/local/lib/emacs/lisp"

** src/epaths.h
- makeによって、epaths.inを素に生成される。
- GNU配布状態: [./configure, makeの結果]
#define PATH_LOADSEARCH "/usr/local/share/emacs/22.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/local/share/emacs/22.2/lisp:/usr/local/share/emacs/22.2/leim"
- Ubuntu: [debuildの結果]
#define PATH_LOADSEARCH "/etc/emacs22:/etc/emacs:/usr/local/share/emacs/22.2/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/22.2/site-lisp:/usr/share/emacs/site-lisp:/usr/share/emacs/22.2/leim:/usr/share/emacs/22.2/lisp:/usr/share/emacs/22.2/leim"

** src/emacs.c
- main
- init_lread関数[lread.c]の実行
- normal = PATH_LOADSEARCH;
- Vload_path = decode_env_path ("EMACSLOADPATH", normal);
- dcode_env_pathはパス達のリストを返す。
- Vtop_level変数の構成
- 起動時に評価するlispを格納。
- 値の形式は(load . (hoge))。すなわちhogeをロー
ドする。
- hogeは、
- emacsオプションで'-l'指定があればそのelファ
イル。
- そうでなければ、'loadup.el'。
- GNU:
(load "loadup.el")
- Frecursive_edit関数の実行
- editor command loop に入る。
- recursive_edit_1 [keyboard.c]
- command_loop [keyboard.c]
- internal_catch (Qtop_level, top_level_1, Qnil)
- top_level_1 [keyboad.c]
- internal_condition_case (top_level_2, Qerror, cmd_error) [eval.c]
- top_level_2 [keyboard.c]
- Feval (Vtop_level) [eval.c]
- ここにいたり、先にVtop_level
で設定した(load "loadup.el")が
評価される。

** lisp/loadup.el
- このelispに入った時点では、emacs.cのVload_path
がload-pathの値である。

*** load-path変数の調整
- bootstrappingするときだけ、load-pathを次のように
加工する。通常はこの加工はしない。

(let ((dir (car load-path)))
;; We'll probably overflow the pure space.
(setq purify-flag nil)
(setq load-path (list dir
(expand-file-name "emacs-lisp" dir)
(expand-file-name "language" dir)
(expand-file-name "international" dir)
(expand-file-name "textmodes" dir))))

*** (load "startup") [lisp/startup.el]
- (defcustom site-run-file "site-start" ...)
- (defconst debian-emacs-flavor 'emacs22 ...)
[*debian patch*]
- (setq top-level '(normal-top-level))
- normal-top-level関数を定義
- この関数の中で次の処理が定義されている。
- load-pathの拡張
- load-pathに含まれるパスを順次処理する。
- 処理は、そのパスに、subdirs.elや
leim-list.elがあれば、それらをloadするとい
うもの。
- subdirs.elの中身の典型は、次の2つ。
- normal-top-level-add-subdirs-\
to-load-path を引数無しで呼ぶ。これは
カレントディレクトリ配下のサブディレク
トリを全てload-pathに追加する。
- normal-top-level-add-subdirs-\
to-load-path を引数有で呼ぶ。これはカ
レントディレクトリ配下のサブディレクト
リについて、引数で指定されたものを
load-pathに追加する。
- leim-list.elの中身の典型は、次のよう。
- register-input-method関数の実行を列記。
- loadやautoloadをここに記述することも
ある。
- command-line関数を実行する。
- emacs-starup-hookを呼ぶ。
- term-startup-hookを呼ぶ。
- command-line関数を定義
- この関数の中で次の処理が定義されている。
- (load site-run-file t t)
- (load "debian-startup" t t nil) [*debian patch*]
- "debian-startup.el"の中身は関数群定義のみ。
- 定義される関数の一覧。
- debian-pkg-add-load-path-item
- debian-unique-strings
- debian-run-directories
- debian-startup
- (debian-startup debian-emacs-flavor)の実行 [*debian patch*]
- (let ((common-dir "/etc/emacs/site-start.d")
(flavor-dir (concat "/etc/" (symbol-name flavor) "/site-start.d")))
(debian-run-directories flavor-dir common-dir))))
- (debian-run-directories flavor-dir common-dir)
- flavor-dirやcommon-dirに入っているすべての
ディレクトリについて、NNfilename.elや
NNfilename.elcの形のファイル名のものを探索
収集し、アルファベティカルにソートして、重
複を削除したリストを作成する。このリス
トをbase-namesと呼ぶ。
- load-pathに、flavor-dirとcommon-dirを追
加する。
- base-namesの中身(file)をひとつずつloadす
る。
- 前項のloadをした結果として、load-pathが
さらに拡張されているかもしれない。そこで、
load-pathをflavor-dirとcommon-dirを追加
しただけの状態に戻す。
- (load site-run-file t t nil) [*debian patch*]

- user-init-file-1の調整
- user-init-file-1は、いわゆる'~/.emacs'となる。
- (load user-init-file-1 t t)
- otherfileの調整
- いわゆる'~/.emacs.d'の中の'init'というファイ
ル。
- (load otherfile t t)
- (load "default" t t)
- inihibit-default-initがnilのときは読み込まな
い。

*** (load "site-load" t)
- 'site-load.el'がload-pathのどこかに存在すれば
それをloadする。

- これはtemacsからemacsをdumpするときに含めたい
elispを指定するために存在している。計算機の速度
が向上しているため最近は使わない。
- そもそもの目的はdumpに含めることなのだが、起動時
に読み込ませるelispの設置場所としても使えると言
えば使える。
- ホストのelisp共通設定は、ここではなく
て'default.el'に書くべきである。そちらはユーザ
によって読み込みの制御ができるから。

*** (load "site-init" t)
- 'site-init.el'がload-pathのどこかに存在すれば
それをloadする。

- これもsite-loadと同種の目的のもの。タイミングが
違う。site-initに書いたものはdumped imageにdoc
stringsが読み込まれる。こちらに書いたものは
dumped imageには読み込まれない。
- そもそもの目的はdumpに含めることなのだが、起動時
に読み込ませるelispの設置場所としても使えると言
えば使える。
- ホストのelisp共通設定は、ここではなく
て'default.el'に書くべきである。そちらはユーザ
によって読み込みの制御ができるから。

- site-init.el [*debian patch*]
- flavor-specificなinfo dirの追加処理が記述され
ている。

*** (eval top-level)
- (eval top-level)
- normal-top-level関数[startup.el]の実行


こつこつ。

0 件のコメント: