2012-09-01

glibcがBusyBoxのsedで動かない理由

glibcのビルドがBusyBoxのsedではうまくいかない理由。

[BusyBox] Why glibc doesn't like busybox sed.

glibc-2.3.2の./configureファイルの、busyboxのsedを拒否ってるところ。

  # Found it, now check the version.
  echo "$as_me:$LINENO: checking version of $SED" >&5
echo $ECHO_N "checking version of $SED... $ECHO_C" >&6
  ac_prog_version=`$SED --version 2>&1 | sed -n 's/^.*GNU sed version 
\([0-9]*\.[0-9.]*\).*$/\1/p'`
  case $ac_prog_version in
    '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
    3.0[2-9]*|3.[1-9]*|[4-9]*)
       ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
    *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;

テストを通過するには、"GNU sed version 3.1"という文字列を返さなければならない。つまり、sedであるだけでは不十分で、GNU sedでなければならないのだ。完全に互換性のある実装だけでは不十分なのだ。コーラのブランドをテストしてる。

正しい修正は、このテストのドタマを割れガラスと釘がいっぱい詰まったバズーカで撃つことだ。なにか意見は?

さらに問題は続く。

[BusyBox] Busybox "expr" is broken.

以下の式は、busyboxとgnuとで異なる挙動をする。

expr "UNKNOWN" \< 5

GNUは5を返すが、BusyBoxは0を返す。このため、perlの検出に失敗する。'perl -V:apiversion'はUNKNOWNを返し、それがperlが古すぎないかどうかの確認に使われている。そして、「お、UNKNOWNは5より小さいな」というわけで、./configureスクリプトはperlを無効化する。

これもsedの問題じゃねーよ。

さらにはこんなクソなworkaroundまで飛び出す始末。

[BusyBox] How to make ./configure happy with busybox's sed version.

これはとても汚いが、まあ./configureスクリプトを騙すことはできる。

--- ../cvs/busybox/editors/sed.c 2004-01-04 00:42:14.000000000 -0600
+++ busybox/editors/sed.c 2004-01-25 12:11:09.426692904 -0600
@@ -1073,6 +1073,14 @@
   bb_perror_msg_and_die("atexit");
 #endif
 
+#define LIE_TO_CONFIGURE
+#ifdef LIE_TO_CONFIGURE
+ if(!strcmp(argv[1],"--version")) {
+  printf("This is not GNU sed version 4.0\n");
+  exit(0);
+ }
+#endif
+
  /* do normal option parsing */
  while ((opt = getopt(argc, argv, "ne:f:")) > 0) {
   switch (opt) {

そもそも諸悪の根源は、glibcのクソなconfigure.inなのだが、それを書き換えるのはだいぶ手間がかかるらしい。

1 comment:

Anonymous said...

exprの話ですが、原文では
> Gnu returns 0, busybox returns 1
とありますね。
GNU exprは0を返すけど、busyboxは1を返すってことですよね。;-)

SolarisとかBSD系とかのexprも確認しましたが、0になりました。