Cygwin bash が改行コードについて融通がきかない件
Cygwin では改行コードを LF のみ(Unix 互換)にしているのですが、Cygwin の bash が 3.1.x ⇒ 3.2.x にアップグレードされてから、CR+LF な改行のスクリプトが動かなくなったりと地味に問題が起こっています。
まあ、改行コードの不一致は問題なので、修正できるものはすればいいと思うのですけれども、拾ってきた tarball とかが CR+LF になっていると目も当てられないのですよね。
参照: http://www002.upp.so-net.ne.jp/tinynealy/cygwin.html, http://cygwin.com/ml/cygwin-announce/2006-10/msg00000.html
しかし、原理的に改行コードを修正できないものもあります。
たとえばアプリケーションやライブラリなどを MinGW で(gcc -mno-cygwin で)ビルドしようとすると、コンパイル結果のプログラムは CR+LF で出力してくれるので、罠にはまることが。Cygwin でビルドすると cygwin1.dll が(しかも特定のバージョンに限定して)必要になってしまうだけに、単体で動かしたくなることってままあると思うのですが…。
たとえば今日も、ライブラリの configure でつまづいてます。次のようなエラーが出たら改行コードのしわざです。(ここでは libogg-1.1.3 を例とします。)
$ export CC='gcc -mno-cygwin' $ ./configure --prefix=/usr/local ... ... checking for short... yes checking size of short... 2 checking for int... yes checking size of int... 4 checking for long... yes checking size of long... 4 checking for long long... yes checking size of long long... 8 configure: error: No 16 bit type found on this platform!
16bit type は short でちゃんと判別されているはずなのに、おかしいですね。config.log の情報を元に configure を覗いてみると、エラー原因は次のブロックにあることがわかります。
if test -z "$SIZE16"; then { { echo "$as_me:$LINENO: error: No 16 bit type found on this platform!" >&5 echo "$as_me: error: No 16 bit type found on this platform!" >&2;} { (exit 1); exit 1; }; } fi
つまりは、変数 SIZE16 が定義されていないためにエラーになっていると。ではこの変数を定義しているところは…? と遡っていくと、こんなコードに行き当たります。
if test x$has_int16_t = "xyes" ; then SIZE16="int16_t" else case 2 in $ac_cv_sizeof_short) SIZE16="short";; $ac_cv_sizeof_int) SIZE16="int";; esac fi
で、種明かしをすると、ここで ac_cv_sizeof_{short,int} を見に行っているわけですが、こいつらが CR まで含んでしまっているためにこういった問題が起こるようです。以下は config.log の抜粋。
configure:19812: checking size of short configure:20124: gcc -mno-cygwin -o conftest.exe -O20 -fsigned-char conftest.c >&5 configure:20127: $? = 0 configure:20129: ./conftest.exe configure:20132: $? = 0 configure:20155: result: 2^M ... configure:21440: error: No 16 bit type found on this platform!
Cygwin の ML でも似たようなことで悩んでいる方がいらっしゃって、それによると configure にクロスコンパイルのためのオプションを指定すればよいとのことです。
http://www.cygwin.com/ml/cygwin/2006-12/threads.html#00011
$ ./configure --prefix=/usr/local --host=i686-pc-mingw32 --build=i686-pc-cygwin \ ...
面倒ですが、私の場合もこれでなんとか(+なぜか)回避ができました。
CR を literally に解釈するようになったかわりに bash に igncr オプションが新設されているらしく、それを指定すると互換動作が行われるそうですが、継承はされないので各プロセスごとに設定する必要があるとか。こちらはスクリプトに仕込むとか ~/.bashrc あたりに仕込むとかいう方法が見られますが、うまく動くかどうか、ちょっと検証ができていません。
また、上記の問題は configure スクリプトが行っているテストによっても発生しないことがあり、たとえば test の -eq 演算子(数値比較)を使うと発生しないようです。(文字列比較の = 演算子や case-esac では発生します。) なので、configure 側をいじるという選択肢もないわけではないですね。