レッツ! コンパイル(2003/08/27)

私は、りなざう(SL-C7x0)が出た当初から、
「これをシリアルコンソールにして、ルータとかの設定が出来たらえ〜な〜」と考えていました。
その後、にゃののん氏がシリアルコンソールにする為の手順をまとめて雑誌に発表しましたが、
私は氏が記事の中で紹介している Minicom があまり好きではなく(だってすぐ画面が崩れるんだもん!!)、
cu コマンドが使えんものかとずっと考えておりましたが、
残念ながらりなざう用の cu のバイナリは誰も公開していないようです。
それならばという事で、自身でえいやっとコンパイルすることにしました。
せっかくなので、セルフコンパイル環境を構築してコンパイル、
ついでに ipk パッケージの作成まで行い、公開することを最終目標とします。

0.前準備
1.セルフコンパイル環境を構築する( dev_img の導入・設定)
2. uucp(cu) をコンパイル・インストールする
3. cu を ipk 形式のパッケージにする
巻末付録(笑). cu_1.07_arm.ipk をインストールする


0.前準備

  1. 以下で行う作業で上手くいかなかった時の為、
    「設定」→「バックアップ/リストア」及び母艦でのバックアップツールで、バックアップを取っておく。
    ※非常に重要。私は、本作業中に5回位リストアした。
  2. 後で cmp コマンドが必要になる為(※1)、予めインストールしておく。
    cmp コマンドは、 diffutils や armutils に含まれている。

    私は、 diffutils_2.7 をインストールした(Naorou Takagiさん、感謝!!)。
    インストール方法は、「設定」→「ソフトウェアの追加と削除」だけの為、割愛。
    diff もインストールされるので、実は本ドキュメントを作成するのに便利だったり(^^;)

  3. ACアダプターを繋いでおく(^^;)
    繋いでおかないと、
    後でひどい目に遭う(^^;)(※3)


1.セルフコンパイル環境を構築する( dev_img の導入・設定)

※セルフコンパイル環境の構築は、たなかとしひささんのサイトを参考に行いました。
 ここにあるのは、自身の作業記録に過ぎません。

  1. 下記より、 dev_img を取得する。

    取得した dev_img は、SDカード( /mnt/card )に置く。

※以下はターミナルから su して作業を行う。

  1. dev_img のマウント先を作成する。
    下記では /mnt/dev_img(実体は /home/system/var/mnt/dev_img ) としている。
    # mkdir /mnt/dev_img
    
  2. /etc/fstab を編集、 dev_img をマウントする為のエントリを追加、マウントする。
    編集内容は diff の出力を参照。
    ※SDカードが何時でも差さっているとは限らないので、起動時に勝手にマウントされないよう、
     マウントオプションに noauto を指定しておく。
    ※ noauto を指定している場合、再起動の度にマウントし直す必要がある。
    # cp -ip /etc/fstab /etc/fstab.bak←一応バックアップ
    # vi /etc/fstab
    # diff /etc/fstab.bak /etc/fstab←バックアップと比較
    6a7
    > /mnt/card/dev_img-1.3 /mnt/dev_img    cramfs  loop,rw,noauto  0  0
    # mount /mnt/dev_img
    # mount←マウントされていることを確認
    :
    /dev/loop0 on /home/system/var/mnt/dev_img type cramfs (rw)
    
  3. マウント出来たら、 dev_img 内の compiler_setup.sh を実行、
    セルフコンパイルが出来るように設定する。
    # /mnt/dev_img/bin/compiler_setup.sh -r /mnt/dev_img
    # /mnt/dev_img/bin/gcc --version←パス指定で gcc が実行出来ることを確認
    2.95.1
    
  4. パス指定をしなくても gcc 等のコマンドが実行出来るよう、
    コマンドサーチパスに dev_img の bin ディレクトリを追加する。
    今回は bash, sh の両方で設定されるよう、 .profile を編集、設定を追加する。
    # cp -ip ~/.profile ~/.profile.bak←一応バックアップ
    # vi ~/.profile
    # diff ~/.profile.bak ~/.profile←バックアップと比較
    7a8
    > PATH=$PATH:/mnt/dev_img/bin
    # . ~/.profile←現在のシェルに設定を反映
    # gcc --version←パス指定無しで gcc が実行出来ることを確認
    2.95.1
    
  5. 実はりなざうはテンポラリ領域( /tmp 、つまり / ) の空き容量が非常に小さいため、
    少しでも大きなファイルをコンパイルしようとするとすぐエラーとなる(※2)。
    その為、 TMP(または TMPDIR ) として別の(空き容量の大きい)ディレクトリを指定する必要がある。
    幸い /var/tmp(実体は /home/system/var/tmp ) があるので、今回はここを使わせてもらうことにした。
    # TMP=/var/tmp; export TMP
    
  6. SL-B500 や SL-C700 の場合、恐らくスワップの設定も必要と思われる。
    私は SL-C760 で作業を行ったため、スワップの設定は特に必要無かった。

これでセルフコンパイルの環境は整った。
※とりあえず Hello World は試したが、ここでは割愛。


2. uucp(cu) をコンパイル・インストールする

Google 等で調べてみたところ、
cu コマンドは uucp のパッケージに含まれている事がわかった。
とりあえず、 uucp パッケージをまるごとコンパイル・インストールしてみる事にする。

  1. Ian Lance Taylor さんが uucp のGNU GPL版を作成・公開しているので、ここからソースパッケージを取得する。
    Thanks to Ian Lance Taylor!!

    取得したソースパッケージ( uucp-1.07.tar.gz )は、 /mnt/card/Document/application/x-gzip に置く。

※以下はターミナルから su して作業を行う。

  1. ソースパッケージを解凍・展開する。
    今回、展開先は /usr/local/source としているが、空き容量さえ十分であれば何処でも良いと思われる。
    # mkdir /usr/local/source←該当ディレクトリを作成
    # cd /usr/local/source
    # gzip -dc /mnt/card/Document/application/x-gzip/uucp-1.07.tar.gz | tar tvf -←内容を確認
    :
    # gzip -dc /mnt/card/Document/application/x-gzip/uucp-1.07.tar.gz | tar xvf -
    :
    
  2. 作業ディレクトリ uucp-1.07 が出来ているので、移動する。
    # ls
    uucp-1.07
    # cd uucp-1.07
    
  3. README ファイルをよく読む(^^;)
    # ls
    :
    README	...
    :
    # more README
    :
    
  4. インクルードファイル policy.h を編集、
    スプール関連のディレクトリ設定を /usr/spool から /var/spool に変更する。
    編集内容は diff の出力を参照。
    これを変更しないと、コンパイル後に cu 等のコマンドが実行出来ない(※5)。
    # cp -ip policy.h policy.h.bak←一応バックアップ
    # vi policy.h
    # diff policy.h.bak policy.h←バックアップと比較
    575,576c575,576
    < #define SPOOLDIR "/usr/spool/uucp"
    < /* #define SPOOLDIR "/var/spool/uucp" */
    ---
    > /* #define SPOOLDIR "/usr/spool/uucp" */
    > #define SPOOLDIR "/var/spool/uucp"
    583,584c583,584
    < #define PUBDIR "/usr/spool/uucppublic"
    < /* #define PUBDIR "/var/spool/uucppublic" */
    ---
    > /* #define PUBDIR "/usr/spool/uucppublic" */
    > #define PUBDIR "/var/spool/uucppublic"
    647,648c647,648
    < #define LOGFILE "/usr/spool/uucp/Log"
    < /* #define LOGFILE "/var/spool/uucp/Log" */
    ---
    > /* #define LOGFILE "/usr/spool/uucp/Log" */
    > #define LOGFILE "/var/spool/uucp/Log"
    654,655c654,655
    < #define STATFILE "/usr/spool/uucp/Stats"
    < /* #define STATFILE "/var/spool/uucp/Stats" */
    ---
    > /* #define STATFILE "/usr/spool/uucp/Stats" */
    > #define STATFILE "/var/spool/uucp/Stats"
    661,662c661,662
    < #define DEBUGFILE "/usr/spool/uucp/Debug"
    < /* #define DEBUGFILE "/var/spool/uucp/Debug" */
    ---
    > /* #define DEBUGFILE "/usr/spool/uucp/Debug" */
    > #define DEBUGFILE "/var/spool/uucp/Debug"
    
  5. ソースパッケージ内の configure を実行、りなざうに適した Makefile を作ってもらう。
    そのまま configure すると
    何故か prefix ディレクトリの設定がおかしくなるので(※4)、
    prefix ディレクトリには明示的に /usr/local(または prefix として望むパス) を指定する必要がある。
    # ./configure --prefix=/usr/local 2>&1 | tee configure.log
    :
    
    ※上記では出力結果をログとして保存している。(configure.log)
    ※1
    cmp コマンドを導入していない場合、ここで cmp コマンドが無いと言われ、
    configure が正しく終了しない。
  6. configure が問題なく終了したら、 make を実行、コンパイルする。
    # make 2>&1 | tee make.log
    :
    
    ※上記では出力結果をログとして保存している。(
    make.log)
    warning が多く出力されているが、これらはソースの記述が現在の C の厳格な基準に沿っていない為に出力される警告で、
    殆どの場合、実害は無い。
    ※2
    デフォルトのテンポラリ領域は空き容量が殆ど無いため、
    テンポラリ領域に充分な空き容量があるディレクトリを指定しないと、
    /tmp が空き容量不足で gcc コマンドが実行出来ないと言われ、 make が Error 終了する。
    ※3
    りなざうのバッテリ駆動時のオートパワーオフ設定は、デフォルトでは10分後となっている。
    コンパイルには時間が掛かるため、ACアダプタを接続しておかないと、
    上記設定のままではコンパイル中に突然電源が切れてしまい、正しくコンパイルされない場合がある。
    #尤も、私はその時ACアダプタが手元に無かった為、
    #バッテリ駆動時のオートパワーオフを30分(MAX)にして何とか対応しました(^^;)
    #本来は、ACアダプタを使用して作業する方が本筋でしょう。
  7. README に書いてある通り、 uuchk コマンドを実行してみる。
    # ./uuchk
    config file: /usr/local/conf/uucp/config
    sys file: /usr/local/conf/uucp/sys
    port file: /usr/local/conf/uucp/port
    dial file: /usr/local/conf/uucp/dial
    dialcode file: /usr/local/conf/uucp/dialcode
    passwd file: /usr/local/conf/uucp/passwd
    call file: /usr/local/conf/uucp/call
    Spool directory /var/spool/uucp
    Public directory /var/spool/uucppublic
    Lock directory /var/spool/uucp
    Log file /var/spool/uucp/Log
    Statistics file /var/spool/uucp/Stats
    Debug file /var/spool/uucp/Debug
    Global debugging level
    uucico -l will strip login names and passwords
    uucico will strip UUCP protocol commands
    Start uuxqt once per uucico invocation
    ./uuchk: no systems found
    
    最下行のメッセージが気になった為調べたところ、どうもりなざうのカーネルが uucp に対応してないっぽい。
    (ちょっと自身無し。日本語ドキュメントが見つけられなかった為、英語のドキュメントからそう解釈した。)
    しかし、私としては cu さえまともに使えればいいので、そのまま作業を続行することにした。
  8. とりあえず make install でインストールする。
    本当は cu 以外はインストールしなくても良いのだが、適切なターゲット指定が解らなかった為、
    まるごとインストールする。
    # make install 2>&1 | tee install.log
    :
    
    ※上記では出力結果をログとして保存している。(
    install.log)
    warning が多く出力されているが、これらはソースの記述が現在の C の厳格な基準に沿っていない為に出力される警告で、
    殆どの場合、実害は無い。
    ※4
    configure を引数無しで(デフォルト設定のまま)行うと、
    何故か prefix が /mnt/dev_img( dev_img のマウント先!!) に設定されてしまい、
    結果、 make install の際に /mnt/dev_img に対してインストールしようとして、 Error 終了することになる。
    #デフォルトの prefix は /usr/local になっているのに...
    #おかげで完全にリストアする羽目になってしまった。バックアップはしとくもんだねぇ(^^;)
  9. 実は cu を動かすためには /var/spool/uucp ディレクトリが必要なので(※6)、
    該当ディレクトリを作成する。
    また、 cu コマンドは、どのユーザで起動してもユーザ uucp に setuid してコマンドを実行するため、
    ディレクトリの所有者を uucp にしておく必要がある。
    # mkdir /var/spool/uucp
    # chown uucp /var/spool/uucp
    
  10. インストールした cu を実行してみる。 /usr/local/bin/cu にインストールしたので、パスは通っているはず。
    シリアルケーブルとして CE-170TS を使用、家のルータである MN128-SOHO Slotin に接続。
    ※ちなみに、 XON/XOFF でフロー制御を行う機器の場合、 cu(uucp) では通信出来ない(未確認)。
    デバイスファイルには /dev/ttyS0(CFのシリアルカードだと違うかも) 、速度は 9600bps を指定する。
    # CE-170TS であまり速い速度を指定すると、データの取りこぼしが多い気がする...
    #ま、シャープ自身はサポートしてるとは言ってないんで、しゃ〜ないかな?
    # cu -l /dev/ttyS0 -s 9600
    Connected.
    AT
    OK
    ATI2
    MN128-SOHO-Slotin
    
    OK
    ~.
    
    Disconnected.
    
    AT コマンドを実行すると、 MN128-SOHO Slotin と通信出来ていることが分かる。
    ちなみに終了するときは、「~」(チルダ)に続いて「.」(ピリオド)を入力する。
    ※5
    所謂通常通りの手順で configure, make, make install を行うと、
    スプール関連のディレクトリが /usr/spool に設定された状態でインストールされる。
    しかし、りなざうには該当ディレクトリが存在せず、また /usr は Read Only の為、新規に作成することも出来ない。
    そのため、 cu コマンドを実行すると、エラー終了する。
    #何故かデバイスファイルが Line in use と出るので紛らわしい(--;)
    しかもこの設定、 configure でも Makefile でも正しく設定出来ない。
    実はこの設定、インクルードファイル policy.h に埋め込みで記述されているので、このファイルを編集、修正する必要がある。
    りなざうの場合、 /var/spool に修正するのが最も適切と思われる。
    ※6
    cu は、 /var/spool/uucp のディレクトリ(実はユーザ uucp のホーム)が無いと実行出来ない。
    #やはりデバイスファイルが Line in use と出るので紛らわしい(--;)
    このディレクトリはデフォルトでは存在しないため(ユーザは存在するのに...)、
    予め作成して、ディレクトリの所有者やパーミッションを適切に設定する必要がある。

これで cu が使えるようになった。満足。
他の uucp 関連のツールは...どうでもいいや。どうせ使わんし(笑)


3. cu を ipk 形式のパッケージにする

とりあえず、コンパイル・インストール・実行を何度も試行することにより、
cu のバイナリと /var/spool/uucp のディレクトリさえあれば cu は実行出来るような気がしてきた。
( uucp のユーザは(何故か)最初から設定されているし...)
てな訳で、この2つを ipk 形式でパッケージングして、何時でも簡単にインストール出来るようにする。
#実際は、このパッケージを作った後リストアして、
#このパッケージだけをいれることで、スマートに cu のみをインストールしようという算段(^^;)

折角の初パッケージングなので、にゃののん氏のドキュメントを参考に、
ipkg-build を使わずに動作を理解しながらやってみることにする。

※以下はターミナルから su して作業を行う。

  1. ホームの下に、作業用ディレクトリ work を作成。
    # cd ~
    # mkdir work
    
  2. 作業用ディレクトリ以下に、パッケージ対象の階層を作成する。
    /usr/local は /home/root/usr/local のシンボリックリンクなので、実際のパスで記述する。
    インストール先の階層が出来たら、そこに cu をコピーする。
    ちなみに、 /var/spool/uucp は空ディレクトリの為アーカイブに出来ないようなので、
    後から postinst で作成することにする。
    # mkdir -p work/home/root/usr/local/bin←横着して、まとめてディレクトリを作っている
    # cp -ip /home/root/usr/local/bin/cu work/home/root/usr/local/bin/cu
    
  3. コントロールファイル用作業ディレクトリ work/work を作成。
    # mkdir work/work
    
  4. コントロールファイル control を作成する。
    Description の内容は、 `cu -v` で表示されるバージョン情報から拝借(^^;)
    # vi work/work/control
    # cat work/work/control←内容を確認
    Package: cu
    Priority: optional
    Section: extras
    Maintainer: luckytamtam@ybb.ne.jp
    Architecture: arm
    Version: 1.07
    Depends:
    Description: cu (Taylor UUCP) 1.07
     Copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor
    
  5. アーカイブ展開前に実行されるシェルスクリプト preinst を作成する。
    一応既にあるファイルを上書きで消してしまわないようにとの配慮だが、とり越し苦労の可能性が大(^^;)
    # vi work/work/preinst
    # cat work/work/preinst←内容を確認
    #!/bin/sh
     
    INSTDIR=/home/root/usr/local/bin
    SPOOLDIR=/home/system/var/spool
     
    if [ -e $INSTDIR/cu ]; then
            mv $INSTDIR/cu $INSTDIR/cu.`date +%y%m%d%H%M%S`.bak
    fi
    if [ -e $SPOOLDIR/uucp ]; then
            mv $SPOOLDIR/uucp $SPOOLDIR/uucp.`date +%y%m%d%H%M%S`.bak
    fi
    
    # chmod 755 work/work/preinst←一応実行属性を付けている。必要かどうかは未確認
    
  6. アーカイブ展開後に実行されるシェルスクリプト postinst を作成する。
    ipk パッケージを「アプリケーションの追加/削除」でインストールすると、
    アーカイブ内のユーザ情報に係らず、ユーザ root, グループ qpe でインストールされるようだが、
    cu は ユーザ uucp 権限でないと正しく動作しない。
    また、パーミッションはある程度引き継ぐようだが(未確認)、 setuid の情報は引き継がれないため、
    ユーザ uucp に setuid する設定は失われてしまう。このため、 chown, chmod で再設定してやる必要がある。
    また、アーカイブに出来なかった /var/spool/uucp を作成、パーミッション設定を行うようにする。
    # vi work/work/postinst
    # cat work/work/postinst←内容を確認
    #!/bin/sh
     
    INSTDIR=/home/root/usr/local/bin
    SPOOLDIR=/home/system/var/spool
     
    chown uucp $INSTDIR/cu
    chmod 4555 $INSTDIR/cu
     
    mkdir $SPOOLDIR/uucp
    chown uucp $SPOOLDIR/uucp
    
    # chmod 755 work/work/postinst←一応実行属性を付けている。必要かどうかは未確認
    
  7. コントロール関連のファイル(今回は control, preinst, postinst )をまとめ、アーカイブ control.tar.gz にする。
    # cd work/work
    # tar cvf ../control.tar ./*←(カレントディレクトリを含む)隠しファイルはアーカイブしない
    :
    # cd ..
    # gzip control.tar
    # rm -rf work←不要になった作業ディレクトリは削除
    # cd ..
    
  8. パッケージ対象のファイル(今回は cu だけ) をまとめ、アーカイブ data.tar.gz にする。
    # cd work
    # tar cvf data.tar ./home←パッケージにするディレクトリだけを指定
    :
    # gzip data.tar
    # rm -rf home←不要になったパッケージ対象の階層は削除
    # cd ..
    
  9. アーカイブ control.tar.gz, data.tar.gz をまとめ、パッケージ cu_1.07_arm.ipk にする。
    # cd work
    # tar cvf ../cu_1.07_arm.tar ./*← control.tar.gz, data.tar.gz を指定しても良い
    :
    # cd ..
    # gzip cu_1.07_arm.tar
    # mv cu_1.07_arm.tar.gz cu_1.07_arm.ipk←リネームすれば、 ipk 形式のパッケージとして認識される
    

これでパッケージは完成した。
実際に使えることも確認している。
巻末付録(笑)を参照のこと。


巻末付録(笑). cu_1.07_arm.ipk をインストールする

  1. 完成したパッケージは、下記の場所に登録しておいた。

    ダウンロードしたら、「設定」→「ソフトウェアの追加と削除」でインストール。
    ちなみに、 SL-C700, SL-C760 では正常に動作することを確認している。

  2. インストールすると、以下のファイルが作成される。
    -r-sr-xr-x    1 uucp     qpe        114420 Aug 22 12:03 /home/root/usr/local/bin/cu
    drwxr-xr-x    2 uucp     qpe             0 ??? ?? ??:?? /home/system/var/spool/uucp
    
    シンボリックリンクにより、其々 /usr/local/bin/cu, /var/spool/uucp としても参照可能。

  3. 一般的な使い方は以下の通り。

    $ cu -l 接続先デバイスファイル名( /dev/ttys0 等) -s 接続速度( 9600 等)
    

    例:
    $ cu -l /dev/ttyS0 -s 9600
    Connected.
    AT
    OK
    ATI2
    MN128-SOHO-Slotin
    
    OK
    ~.
    
    Disconnected.
    

    終了するときは、「~」(チルダ)に続いて「.」(ピリオド)を入力する。

    以下のように入力すれば、使い方が表示される。

    $ cu --help
    

    また、以下のように入力すれば、バージョン情報等が表示される。
    ちなみに、ここでもこのソフトウェアがGPLであることが確認出来る。

    $ cu -v
    

  4. 注意点を幾つか。

    ※ XON/XOFF でフロー制御を行う機器は、 cu では通信出来ない(未確認)。
    ※「~」(チルダ)を入力する必要がある機器は、 cu では通信出来ない可能性がある(未確認)。


この駄文に責任を持たない人: たむたむ

戻る