2006年1月24日火曜日

FreeBSD上で玄箱用tcshをクロスコンパイル

苦労して作ったクロスコンパイラで、玄箱用のtcshをコンパイルしてみました。



FreeBSDで使っているシェルがtcshなので、やっぱりLinuxでもtcshを使いたいのです。普段から使い慣れた道具が変わってしまうと、とっても不自由しますからね。



クロスコンパイルなので、当然、コンパイル作業はFreeBSD上で行いますが、ちょっとした理由があり、面倒が少なくなるように(後述)、玄箱のディスクをNFSマウントして、玄箱のディスク上で行います。



作業ディレクトリを作成し、tcshのソースファイルを展開します。

% cd /net/kuro-box/mnt/share
% mkdir tmp
% cd tmp
% tar zxf /net/kuro-box/mnt/share/tcsh-6.14.00.tar.gz
% cd tcsh-6.14.00/

クロスコンパイラへのPATHを通しておきます。

% setenv PATH /usr/local/kuro-box/bin:$PATH

configureを実行します。

% ./configure --host=powerpc-hardhat-linux



configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... i386-unknown-freebsd6.0
checking host system type... powerpc-hardhat-linux-gnu
checking cached host tuple... ok
Tcsh will use configuration file `linux'.
checking for powerpc-hardhat-linux-gcc... powerpc-hardhat-linux-gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... yes
(省略)
checking whether getpgrp requires zero arguments... yes
checking whether setpgrp takes no argument... configure: error: cannot check setpgrp when cross compiling

あーあ、エラーで終わってしまいました。



このエラーの原因は、configure.inでかかれている、autoconfのAC_FUNC_SETPGRPマクロというのが原因です。configure実行中に、プログラムをコンパイルし実行しようとするのですが、今は玄箱用にクロスコンパイルしようとしているので、コンパイルされたプログラムはFreeBSD上で実行できません。



おそらく礼儀正しい訂正方法としては、configure.inのなかのAC_FUNC_SETPGRPをコメントアウトして、autoconfを実行し、configureを生成しなおす、ということになると思いますが、多くの人にとって、その作業はかえって



めんどくさいので



configureを直接書き換えます。乱暴なやりかたですね。実は、別の理由があったりします。それはあとで。



書き換えるべきところは、ここです。

echo "$as_me:$LINENO: checking whether setpgrp takes no argument" >&5
echo $ECHO_N "checking whether setpgrp takes no argument... $ECHO_C" >&6

というところから

cat >>confdefs.h <<\_ACEOF
#define SETPGRP_VOID 1
_ACEOF



fi

というところまでを、削除します。



もう一度、configureを実行します。

% ./configure --host=powerpc-hardhat-linux



checking for strerror... yes
checking for strstr... yes
checking for sysconf... yes
checking for wcwidth... yes
checking whether getpgrp requires zero arguments... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h

コンパイルします。ちゃんとpowerpc-hardhat-linux-gccというコマンドでコンパイルされていますね。

% gmake
grep 'ERR_' ./sh.err.c | grep '^#define' >> sh.err.h
powerpc-hardhat-linux-gcc -E  -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'
-D_h_tc_const\
    ./tc.const.c | \
    sed -n -e 's/^\(Char STR[a-zA-Z0-9_]*\) *\[ *\].*/extern \1[];/p' | \
    sort >> tc.const.h
powerpc-hardhat-linux-gcc  -c -g -O2             -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    sh.c
powerpc-hardhat-linux-gcc  -c -g -O2             -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    sh.dir.c
(省略)

うまくいきそう・・・と思ったら、エラーになりました。

powerpc-hardhat-linux-gcc  -c -g -O2             -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    tc.const.c
rm -f gethost
powerpc-hardhat-linux-gcc  -o gethost  -g -O2            -I. -I. -D_PATH_TCSHELL
='"/usr/local/bin/tcsh"'   ./gethost.c -lcurses -lcrypt



./gethost ./host.defs >> tc.defs.c
./gethost: 1: Syntax error: "(" unexpected
gmake: *** [tc.defs.c] Error 2

これは、コンパイルされたgethostというコマンドを実行しようとして、エラーになっています。gethostは玄箱で実行できるようにコンパイルされているので、FreeBSD上では実行できなくて当然です。



仕方ないので、この部分だけは、玄箱で実行します。実は、玄箱のディスク上でコンパイル作業を行ったのは、ここで、ファイルを玄箱へコピーする手間を省くためだったのです。



玄箱にログインし、先ほどエラーになったコマンド「./gethost ./host.defs >> tc.defs.c」を手で入力して実行します。



root@KURO-BOX:/mnt/share/tmp/tcsh-6.14.00# ./gethost ./host.defs >> tc.defs.c
root@KURO-BOX:/mnt/share/tmp/tcsh-6.14.00# ls -l tc.defs.c
-rw-r--r--    1 1001     1001        55160 Jan 17 09:19 tc.defs.c



どうも玄箱の時計がくるっていたようです(よくあることらしいです)。このままでは、ファイルのタイムスタンプがおかしくて、うまくmakeできないので、touchで修正します。

% touch tc.defs.c
% ls -l tc.defs.c
-rw-r--r--  1 nhh  wheel  55160 Jan 23 22:48 tc.defs.c

FreeBSD上で、つづきをコンパイルします。

% gmake
powerpc-hardhat-linux-gcc  -c -g -O2             -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    tc.defs.c
powerpc-hardhat-linux-gcc  -c -g -O2             -I. -I. -D_PATH_TCSHELL='"/usr/local/bin/tcsh"'    tc.disc.c
(省略)





powerpc-hardhat-linux-gcc  -o tcsh  -g -O2               -I. -I. sh.o sh.dir.o sh.dol.o sh.err.o sh.exec.o sh.char.o sh.exp.o sh.file.o sh.func.o sh.glob.o sh.hist.o sh.init.o sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.proc.o sh.sem.o sh.set.o sh.time.o glob.o mi.termios.o ma.setp.o vms.termcap.o tw.help.o tw.init.o tw.parse.o tw.spell.o tw.comp.o tw.color.o ed.chared.o ed.refresh.o ed.screen.o ed.init.o ed.inputl.o ed.defns.o ed.xmap.o ed.term.o tc.alloc.o tc.bind.o tc.const.o tc.defs.o tc.disc.o tc.func.o tc.nls.o tc.os.o tc.printf.o tc.prompt.o tc.sched.o tc.sig.o tc.str.o tc.vers.o tc.who.o  -lcurses -lcrypt



% ls -l tcsh
-rwxr-xr-x  1 nhh  wheel  1030571 Jan 23 22:50 tcsh*

できました!



玄箱で実行します。



root@KURO-BOX:/mnt/share/tmp/tcsh-6.14.00# ./tcsh



# echo $version
tcsh 6.14.00 (Astron) 2005-03-25 (powerpc-apple-mklinux) options wide,nls,dl,al,kan,rh,color,filec



# ls-F /sbin
/sbin:
agetty*                 install-info*           murasaki.pci*
badblocks*              ipmaddr*                murasaki.usb*
calib_time*             kallsyms@               murasaki_init.pci*
chkwebpasswd*           kernelversion*          murasaki_init.usb*
depmod*                 killall*                pmap_dump*



動いているみたいですね。





■ 玄箱ではNFS lock がうまく動かないみたい



configure.inを書き換えて、



dnl AC_FUNC_SETPGRP



autoconfを実行したところ、



% autoconf259
autom4te259: cannot lock autom4te.cache/requests with mode 2 (perhaps you are running make -j on a lame NFS client?): Operation not supported



または



autom4te259: cannot lock autom4te.cache/requests with mode 2 (perhaps you are running make -j on a lame NFS client?): No route to host



というエラーがでました。FreeBSD側でrpc.lockdを動かしているかどうかでエラーメッセージが異なるようです。



玄箱にも/usr/sbin/rpc.lockdやrpc.statdがあるので、これを動かせばいいのか、と思いきや、なんか動いていません。カーネルのサポートが必要なのかもしれませんが、よくわからないので、見なかったことにして、NFS lockのことは忘れることにしました。



1 件のコメント:

  1. 通りすがり2009年5月19日 2:04

    /usr/local/bin/autom4te259
    古い記事なのでものすごく今更かもしれませんが、上記ファイルの以下
    の行をコメントアウトしてしまえば、LOCK_EX処理を行わないので、エラー
    は回避できますよ~。
    $icache_file->lock (LOCK_EX);

    返信削除