The Mule

(v1.02, Apr. 4, 2000)

さて、懸案の一つ、emacs のポートを片付ける。 Emacs の build が難しいのは、途中で自分自身を dump する必要があることにあった。

  1. 自分自身を動かすということは当然クロスコンパイルに対応していない。
  2. dump したものを再利用するため、OS に強く依存する。
Emacs 19.26 の時代にどこかで arm にポートされることはされたらしいと Changelog にある。しかしこの時代は arm といっても Acorn の RICSiX で、machine 定義は Acorn 専用 (src/m/acorn.h) になっている。 Acorn RISC PC の上で X を使っている ARM Linux Project 本家の人達でさえよくみれば (emacs でなく) micro emacs ばっかり ── と書きかけて、あら、スクリーンショットがなくなってる ....。

(気を取りなおして、) arm linux 用の定義の src/m/arm.h が emacs ソースツリーに姿をあらわすのは Debian の中の emacs20-dl からだ(本家の emacs20-dl には入ってない)。 しかし emacs 20 は大きすぎる ... X を外しても 3M バイト。 一方、mule 2.3-19.34 は X 込みで 2.4M バイト。 もっとも nemacs 18.59 は X 込みで 780k バイトなわけで、 2.4MB と 3.0MB じゃ五十歩百歩という話もないでもないけども。 ま、8MB のメモリしかもたない Psion5 では 600kB というのはそれなりに貴重だ、 というわけで mule 2.3-19.34 を動かす。 mule が重かったら nemacs も考えないといけないけど mule と nemacs を同時に持つだけのカードの余裕はないので mule を先に見ることにする。

mule for linux/i386

Linux/i386 用の mule はほとんど一撃で作れる:
% zcat mule-2.3-19.34-alpha01.tar.gz |tar -xv
% cd mule-2.3-19.34-alpha01
% zcat ../mule2_2.3+19.34-8.diff.gz | patch -p1
% ./configure --without-x --with-canna --with-canna-includes=/usr/local/canna/include
% make |& tee ../make.i386.log
しばらくほっとくと src/temacs が出来、 こいつが lisp/*.el を順繰りにバイトコンパイルし、 つづいで loadup で lisp/*.elc を吸い上げて dump して src/emacs-19.34 (mule 本体) ができる。

ここまではソースが壊れてないことの単なる確認。次のステップに移る ──

ソースツリーの分離

必ずしも必要ないが、ソースツリーとターゲットツリーを分離しておく。 目的は二つ。 先の make を眺めていれば、 temacs のことを除いても w3m の時のようにコンパイルしたばっかりのサブコマンドを動かすケースが多い。 いつでも i386 側からバイナリを持ち込めるようにするためと、 もう一つは Psion5 のカードは小さく、... って 96MB あるんだから 世間の標準でいえばべつに小さいというほどじゃないけど、 mule はソースツリーで 45M バイト、それにコンパイル中のオブジェクトが 13M バイトあり 96MB ではソースツリーを納めるには小さすぎるので temacs を Psion5 に持ち込む時に 必要ないファイルは持ち込みたくない(持ち込めない)のでその分離を簡単にしたい。

ああ、そういう意味では ソース 45MB、中間オブジェクトに 15MB、コンパイラに都合 10MB を納めて 128MB 位のカードがあればセルフで mule を build することは出来る。 .... なんかとてつもなく遅そうだけど ....

閑話休題。

% cd ..
% md mule-i386
% cd mule-i386
% ../mule-2.3-19.34-alpha01/configure  --srcdir=/home/src/psion/emacs/mule-2.3-19.34-alpha01 --without-x --with-canna --with-canna-includes=/usr/local/canna/include
とすればソース、オブジェクトが分離され、
% make
で同じように build できることになってるけど emacs の configure はそうなってなかった -_-;
configure が悪いのか手もとの make が悪いのか、ともかく各 Makefile.in
srcdir=@srcdir@
VPATH=@srcdir@
の記述を、Makefile.in が dir の下にあるとして、
srcdir=@srcdir@/dir
VPATH=@srcdir@/dir 
のように全部書き直さないといけなかった。この状態なら
% ../mule-2.3-19.34-alpha01/configure  --srcdir=/home/src/psion/emacs/mule-2.3-19.34-alpha01 --without-x --with-canna --with-canna-includes=/usr/local/canna/include
% make
で再び mule をつくることができる。

CC を置き換えての mule for linux/i386

arm 用の mule の build に入る前にもう一つステップをはさむ。
% make clean
% rm config.cache
% CC=i586-linux-gnulibc2-gcc ../mule-2.3-19.34-alpha01/configure  --srcdir=/home/src/psion/emacs/mule-2.3-19.34-alpha01 --without-x --with-canna --with-canna-includes=/usr/local/canna/include
% make
しつこく i386 用の make を続けてるけど、今回の make の意義は (arm 用に make する前に) arm 固有の挙動なのかそのコンパイラの系統(クロスの gcc 2.95.2, glibc 2.1) の挙動なのかを分離することにある。 i586-linux-gnulibc2-gccarm-linux-gcc と同期のコンパイラ... というかなんというか、 同時期に同じソースツリーから作られた linux/i386 (glibc 2.1) 用の linux/i386 の上で動くクロスコンパイラで、 もちろん configure や Makefile がどのていどクロスに対応しているのかのチェックにも使える。

ここでは movemail の make の時に -llockfile がないといって怒られるのと、temacs のリンクの時に /usr/lib/crt1.o が違うぞといって怒られた。 前者は -llockfile を消して、後者は正しい /usr/local/i586-linux-gnulibc2/lib/crt1.o を指定すると通った。
... この程度ならいきなり arm 用に入っても問題なかったかも (こらこら、冒頭のえらそーな記述はナンだったんだ?)。

さてソースツリーの下ごしらえは終った。これから arm 向けの作業に入る。

Now You See It ──

% cd ..
% md mule-arm
% cd mule-arm
% CC=arm-linux-gcc ../mule-2.3-19.34-alpha01/configure  --srcdir=/home/src/psion/emacs/mule-2.3-19.34-alpha01 --build=i586-linux --host=arm-linux --without-x --with-canna
当然だけど一発で落ちる:-)
loading cache ./config.cache
checking host system type... arm-unknown-linux-gnu
configure: error: Emacs hasn't been ported to `arm-unknown-linux-gnu' systems.
Check `etc/MACHINES' for recognized configuration names.
Debian の emacs20-dl から src/m/arm.h を拾って来て src/m/ にコピーし、 configure に arm-*-linux-gnu* の項を付け加える。
+   arm-*-linux-gnu* )
+     machine=arm opsys=gnu-linux
+   ;;
たぶんどこでもいいと思うので、Acorn の下に書いておいた。 これで configure は通るようになる。
% CC=arm-linux-gcc ../mule-2.3-19.34-alpha01/configure  --srcdir=/home/src/psion/emacs/mule-2.3-19.34-alpha01 --build=i586-linux --host=arm-linux --without-x --with-canna
% make |& tee ../make.arm.log
といきごんで make に入るとやっぱり make は直ちに落ちる:
arm-linux-gcc -D_BSD_SOURCE     -DHAVE_CONFIG_H    -I. -I../src -I/home/src/psion/emacs/mule-2.3-19.34-alpha01/lib-src -I/home/src/psion/emacs/mule-2.3-19.34-alpha01/lib-src/../src   -O2 -o test-distrib /home/src/psion/emacs/mule-2.3-19.34-alpha01/lib-src/test-distrib.c
./test-distrib /home/src/psion/emacs/mule-2.3-19.34-alpha01/lib-src/testfile
./test-distrib: ./test-distrib: cannot execute binary file
make[1]: *** [test-distrib] Error 126
make[1]: Leaving directory `/home/src/psion/emacs/mule-arm/lib-src'
make: *** [lib-src] Error 2
要するに最初にコンパイルする test-distrib は i386 用に make してやらないといけないと。 となりの ../mule-i386/ から test-distrib をコピーし、make を続行する。
% cp ../mule-i386/lib-src/test-distrib lib-src
% touch lib-src/test-distrib
% make |& tee -a ../make.arm.log
次は movemail で -llockfile が無いと言って落ち、つづいて temacs のリンクで止まる。 ここでは例によって crt*.o の位置を /usr/lib から /usr/local/arm-linux に書き換える他、prefix-args というバイナリを 隣の mule-i386/ からもってきておく必要があるらしい。
temacs のリンクに成功し、make-docs を i386 バイナリに交換すれば次は dump で ──
./temacs -batch -l loadup dump
./temacs: ./temacs: cannot execute binary file
make[1]: *** [emacs] Error 126
と止まる。

── And Now You Don't

temacs for arm linux を linux/i386 で動かす方法は無い。 したがって temacs の dump だけは Psion5 上で行う。必要なのは の 3 系統。なお mule-i386 を並行して事前に作っておいた御利益として、 lisp/ にはバイナリ *.elc もできているはずだ。この elc は arm 用にも共有できる。 さて、以上の 3 つをぜんぶ Psion5 に持ち込む。 カードの空きが少しばかり足りなかったのでカードから canna や /usr/doc, /usr/man, /usr/info など emacs の build には必要なさそうなものを追い出して 35MB ほど空きを作った。
ちなみに 96MB もあるのに足りなくなる事態になったのは gcc が入ってるからで、 これが削れればかなり空く。しかしいざという時にセルフで make できるようにしておくほうを優先している。

カード上にいままで build してきたのと同じパス上にツリーを展開し、

% cd src
% ./temacs -batch -l loadup dump
と手で実行すると無事 emacs-19.34 が出来上がった。
% ls -l emacs*
-rwxr-xr--   1 kensyu   users     2402741 Apr  2 16:30 emacs
-rwxr-xr--   1 kensyu   users     2402741 Apr  2 16:30 emacs-19.34.1
-rw-r--r--   1 kensyu   users       18560 Apr  2 15:30 emacs.o
このサイズは CFLAGS に "-O2" を指定したもので、普通にやると "-g -O" となって もう少し大きくなると思う。 もっと小さくしたいからといって strip --strip-all してはマズいらしく、 2.2MB になった、と喜んだところで起動すると segmentation fault で落ちた。

とりあえずオープニングメッセージ:

mule opening, 640x240
~/.emacs を母艦から持ち込んで調整するのはこれからだ。
パッチとバイナリの公開は、広げまくったコードを整理してからってことで mOm
[日記へ] [目次へ]