CentOS 4.4 で GLIBC 2.4 を build するのを諦めた話

宇宙線研の計算機で Dropbox を使おうとしたら、GLIBC が古いと怒られて使えませんでした。

$ wget "http://www.dropbox.com/download/?plat=lnx.x86_64"
$ tar zxvf dropbox-lnx.x86_64-1.1.35.tar.gz
$ ./.dropbox-dist/dropbox
./.dropbox-dist/dropbox: /lib64/tls/libc.so.6: version `GLIBC_2.4' not found (required by ./.dropbox-dist/dropbox)

環境は CentOS 4.4 なのですが、こいつに入っているのは GLIBC 2.3.4 でちょっと古い。共用計算機のため root 権限がないため、自分で GLIBC を入れるしかありません。

$ /lib64/tls/libc.so.6
GNU C Library stable release version 2.3.4, by Roland McGrath et al.

まず、GLIBC 2.4 を落とします。2.5 以降でもいいのですが、あまり新し過ぎて他の場所で不整合が出たら嫌だったので、2.4 にしました。GLIBC の build なんて初めてなので、よく分かんないのですが。

$ wget http://ftp.gnu.org/gnu/glibc/glibc-2.4.tar.gz

展開した後、build 用の directory を作成して移動します。ここが他のソフトと若干違うところ。移動先から configure して、make します。ただし、最後でこけます。

$ tar zxvf glibc-2.4.tar.gz
$ mkdir glibc-2.4-build
$ cd glibc-2.4-build
$ ../glibc-2.4/configure --prefix=$HOME/opt --enable-shared
$ make -j 4
(略)
make[2]: Entering directory `/can/home/oxon/sw/glibc-2.4/inet'
gcc ../sysdeps/unix/sysv/linux/if_index.c -c -std=gnu99 -O2 -Wall -Winline -Wwrite-strings -fmerge-all-constants -g -Wstrict-prototypes      -I../include -I/can/home/oxon/sw/glibc-2.4-build/inet -I/can/home/oxon/sw/glibc-2.4-build -I../sysdeps/x86_64/elf -I../nptl/sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/wordsize-64 -I../nptl/sysdeps/unix/sysv/linux -I../nptl/sysdeps/pthread -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu -I../sysdeps/unix/common -I../sysdeps/unix/mman -I../sysdeps/unix/inet -I../nptl/sysdeps/unix/sysv -I../sysdeps/unix/sysv -I../sysdeps/unix/x86_64 -I../nptl/sysdeps/unix -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/x86_64/fpu -I../nptl/sysdeps/x86_64 -I../sysdeps/x86_64 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic/elf -I../sysdeps/generic -I../nptl  -I.. -I../libio -I. -I /lib/modules/2.6.9-78.0.5.ELsmp/build/include -D_LIBC_REENTRANT -include ../include/libc-symbols.h       -o /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o -MD -MP -MF /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o.dt -MT /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o
In file included from /lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/netlink.h:5,
                 from ../sysdeps/unix/sysv/linux/netlinkaccess.h:23,
                 from ../sysdeps/unix/sysv/linux/if_index.c:32:
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: error: syntax error before "__sum16"
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: warning: type defaults to `int' in declaration of `__sum16'
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: warning: data definition has no type or storage class
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: error: syntax error before "__wsum"
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: warning: type defaults to `int' in declaration of `__wsum'
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: warning: data definition has no type or storage class
make[2]: *** [/can/home/oxon/sw/glibc-2.4-build/inet/if_index.o] Error 1
make[2]: Leaving directory `/can/home/oxon/sw/glibc-2.4/inet'
make[1]: *** [inet/subdir_lib] Error 2
make[1]: Leaving directory `/can/home/oxon/sw/glibc-2.4'
make: *** [all] Error 2

少し検索してみたところ、これは GLIBC の bug ではなく、kernel header の bug だとのこと。なので、kernel header が修正されないと build できません。しかし管理者権限は持っていない。

そこで、ちょっとゴニョゴニョして build できるようにします。

まず、最後の command を実行しているのは glibc-2.4/inet なので、ここに移動します。

$ cd ../glibc-2.4/inet

問題のある header は /lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h なので、これを手元に持ってきます。

$ mkdir linux
$ cp /lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h linux

Error message にある通り、158 行目と 159 行目が問題なので、これを comment out してしまいます。

/*
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;
*/

そして、make でこけた command を実行します。何事もなく通ります。

gcc ../sysdeps/unix/sysv/linux/if_index.c -c -std=gnu99 -O2 -Wall -Winline -Wwrite-strings -fmerge-all-constants -g -Wstrict-prototypes      -I../include -I/can/home/oxon/sw/glibc-2.4-build/inet -I/can/home/oxon/sw/glibc-2.4-build -I../sysdeps/x86_64/elf -I../nptl/sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/wordsize-64 -I../nptl/sysdeps/unix/sysv/linux -I../nptl/sysdeps/pthread -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu -I../sysdeps/unix/common -I../sysdeps/unix/mman -I../sysdeps/unix/inet -I../nptl/sysdeps/unix/sysv -I../sysdeps/unix/sysv -I../sysdeps/unix/x86_64 -I../nptl/sysdeps/unix -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/x86_64/fpu -I../nptl/sysdeps/x86_64 -I../sysdeps/x86_64 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic/elf -I../sysdeps/generic -I../nptl  -I.. -I../libio -I. -I /lib/modules/2.6.9-78.0.5.ELsmp/build/include -D_LIBC_REENTRANT -include ../include/libc-symbols.h       -o /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o -MD -MP -MF /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o.dt -MT /can/home/oxon/sw/glibc-2.4-build/inet/if_index.o

再び build 用の directory に戻って、make の続きを進めます。

$ cd ../../glibc-2.4-build
$ make -j 4

今度は他の場所で同じ error が出るので、同じ手順で作業を繰り返します。

gcc selinux.c -c -std=gnu99 -O2 -Wall -Winline -Wwrite-strings -fmerge-all-constants -g -Wstrict-prototypes   -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 -fpie   -I../include -I/can/home/oxon/sw/glibc-2.4-build/nscd -I/can/home/oxon/sw/glibc-2.4-build -I../sysdeps/x86_64/elf -I../nptl/sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/x86_64 -I../sysdeps/unix/sysv/linux/wordsize-64 -I../nptl/sysdeps/unix/sysv/linux -I../nptl/sysdeps/pthread -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux -I../sysdeps/gnu -I../sysdeps/unix/common -I../sysdeps/unix/mman -I../sysdeps/unix/inet -I../nptl/sysdeps/unix/sysv -I../sysdeps/unix/sysv -I../sysdeps/unix/x86_64 -I../nptl/sysdeps/unix -I../sysdeps/unix -I../sysdeps/posix -I../sysdeps/x86_64/fpu -I../nptl/sysdeps/x86_64 -I../sysdeps/x86_64 -I../sysdeps/wordsize-64 -I../sysdeps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/ieee754 -I../sysdeps/generic/elf -I../sysdeps/generic -I../nptl  -I.. -I../libio -I.  -D_LIBC_REENTRANT -include ../include/libc-symbols.h   -DNOT_IN_libc=1    -o /can/home/oxon/sw/glibc-2.4-build/nscd/selinux.o -MD -MP -MF /can/home/oxon/sw/glibc-2.4-build/nscd/selinux.o.dt -MT /can/home/oxon/sw/glibc-2.4-build/nscd/selinux.o
In file included from /lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/netlink.h:5,
                 from ../sysdeps/unix/sysv/linux/check_pf.c:29,
                 from gai.c:32:
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: error: syntax error before "__sum16"
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: warning: type defaults to `int' in declaration of `__sum16'
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:158: warning: data definition has no type or storage class
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: error: syntax error before "__wsum"
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: warning: type defaults to `int' in declaration of `__wsum'
/lib/modules/2.6.9-78.0.5.ELsmp/build/include/linux/types.h:159: warning: data definition has no type or storage class
make[2]: *** [/can/home/oxon/sw/glibc-2.4-build/nscd/gai.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory `/can/home/oxon/sw/glibc-2.4/nscd'
make[1]: *** [nscd/others] Error 2
make[1]: Leaving directory `/can/home/oxon/sw/glibc-2.4'
make: *** [all] Error 2

こけるのは 2 回だけで、後はうまく通りました。make install します。そうすると、今度は ~/etc/ld.so.conf が見つからないと言われます。

$ make install
(略)
test ! -x /can/home/oxon/sw/glibc-2.4-build/elf/ldconfig || LC_ALL=C LANGUAGE=C \
  /can/home/oxon/sw/glibc-2.4-build/elf/ldconfig  \
			       /can/home/oxon/opt/lib /can/home/oxon/opt/lib
/can/home/oxon/sw/glibc-2.4-build/elf/ldconfig: Can't open configuration file /can/home/oxon/opt/etc/ld.so.conf: No such file or directory
make[1]: Leaving directory `/can/home/oxon/sw/glibc-2.4'

本当は /etc/ld.so.conf を見て欲しいのですが、今回は管理者権限がないために $HOME/opt を prefix にしています。そのため、$HOME/opt/ld.so.conf が無いと言われます。これは copy して、make install を再開します。

$ cp -pr /etc/ld.so.conf /etc/ld.so.conf.d ~/opt/etc
$ make install

$HOME/opt/lib に LD_LIBRARY_PATH を通して、Dropbox を再実行します。

$ cd
$ export LD_LIBRARY_PATH=$HOME/opt/lib:$LD_LIBRARY_PATH
$ ./.dropbox-dist/dropbox                                  
zsh: segmentation fault  ./.dropbox-dist/dropbox

あれ、seg fault でこけた。単純に GLIBC を自分で build すれば良いってもんじゃないのか?

Dropbox に限らず、GLIBC を使っているであろう全ての command がのきなみ seg fault を起こしました。ls とかも駄目です。LD_LIBRARY_PATH を外して逃げる。

$ unset LD_LIBRARY_PATH