ポストに定額給付金を振り込みました、というはがきが届いていました。はがきには4月16日と日付が打ってあります。
口座をチェックするとお金も入っている様子。4月21日に振り込まれたそうです。はがきの日付と全く合ってないが、まあいいか…。
(※)画像はネットバンクの画面キャプチャですが、残高を示す表が無駄にでかかったのでかなり端折っています。
この記事にコメントする
目次: Linux
サーバでプログラムをmakeすると、挙動が違うことに気づきました。
例えばsed-4.1.5ですと、デスクトップのVM上でコンパイルすると何事もなく成功するのに、サーバでコンパイルするとsed-4.1.5/po以下の *.poファイルを更新しようとして失敗し、コンパイルがコケてしまいます。
デスクトップ、サーバともにDebian GNU/Linux 5.0(Lenny)ですから、コンパイラを始めとしたツールの差はなく、環境変数も同じですし、全く同じソースを利用しています。にも関わらずコンパイルに成功したり、しなかったりするのはなんなのでしょうか?
どうやら使っているツールや環境変数、ソースコードまで同じなのに動作が異なるという現象が起きうるようです。
まずはオーソドックスな手順(※)でコンパイルを進めてみて、違いが出る場所を調べました。configureのログは違いなしですが、makeのログは一行目から既に違っています。
make all-recursive make[1]: Entering directory `/home/katsuhiro/build/sed-4.1.5' Making all in intl make[2]: Entering directory `/home/katsuhiro/build/sed-4.1.5/intl' (... 以下、略 ...)
デスクトップではビルド用のディレクトリ(build/sed-4.1.5)に入って、コンパイルが始まります。
cd /home/katsuhiro/src/sed-4.1.5 && /bin/sh /home/katsuhiro/src/sed-4.1.5/config/missing --run aclocal-1.9 -I config cd /home/katsuhiro/src/sed-4.1.5 && /bin/sh /home/katsuhiro/src/sed-4.1.5/config/missing --run automake-1.9 --gnits doc/Makefile.am:29: docdir was already defined in condition TRUE, which includes condition BUILD_HTML ... (... 以下、略 ...)
対するサーバではソース用のディレクトリ(src/sed-4.1.5)に入って、configureやMakefileの更新が始まります。
なぜこんな違いが出るかというと、ビルドディレクトリのMakefile(build/sed-4.1.5/Makefile)にある、ACLOCAL_M4ターゲットが適用されるか、されないかが異なるためです。
(... 関係ない部分なので略 ...)
48: ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
49: am__aclocal_m4_deps = $(top_srcdir)/config/codeset.m4 \r(... 中略 ...)
60: $(top_srcdir)/config/strverscmp.m4 $(top_srcdir)/configure.ac
(... 関係ない部分なので略 ...)
92: ACLOCAL = ${SHELL} /home/katsuhiro/src/sed-4.1.5/config/missing --run aclocal-1.9
(... 関係ない部分なので略 ...)
260: $(ACLOCAL_M4): $(am__aclocal_m4_deps)
261: cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
(... 関係ない部分なので略 ...)
一応補足しておくと260行目の定義は「ソースディレクトリのaclocal.m4がconfig/*.m4より古かったら、missing --run aclocal-1.9を実行してね。」という意味です。
つまりデスクトップではaclocal.m4が古いとみなされないのに、サーバではaclocal.m4が古いとみなされるという違いがあるのです。
(※)sedに限らずGNU autotoolsを使ったソースコードをコンパイルする際は、ソースを展開したディレクトリ(例: ~/src/sed-4.1.5)の他に、ビルド用のディレクトリ(例: ~/build/sed-4.1.5)を作成し、ビルド用のディレクトリでコンフィグおよびコンパイル(例: cd ~/build/sed-4.1.5 && ~/src/sed-4.1.5/configure && make && make install)ができます。
どうやらデスクトップとサーバではファイルの新旧が異なるようです。
ではmakeがファイルの新旧をどう判断しているかというと、実はファイルの更新時刻を比較しているだけです。ですからデスクトップではaclocal.m4とconfig/*.m4が同じ更新時刻になっているが、サーバでは更新時刻が異なっていてなおかつaclocal.m4の方が古い時刻になっている、と考えられます。
ファイルの更新時刻はlsコマンドでわかりますが、より詳しい更新時刻を見るためにls --full-timeオプションをつけて調べます。
$ ls --full-time aclocal.m4 config/*.m4 -rw-r--r-- 1 katsuhiro katsuhiro 31965 2009-04-08 21:59:07.000000000 +0900 aclocal.m4 -rw-r--r-- 1 katsuhiro katsuhiro 894 2009-04-08 21:59:07.000000000 +0900 config/codeset.m4 -rw-r--r-- 1 katsuhiro katsuhiro 1394 2009-04-08 21:59:07.000000000 +0900 config/getline.m4 (... 中略 ...) -rw-r--r-- 1 katsuhiro katsuhiro 733 2009-04-08 21:59:07.000000000 +0900 config/strverscmp.m4
デスクトップではナノ秒の部分は全て0に設定されており、どのファイルも同じ更新時間です。
$ ls --full-time aclocal.m4 config/*.m4 -rw-r--r-- 1 katsuhiro katsuhiro 31965 2009-04-08 22:00:53.953952850 +0900 aclocal.m4 -rw-r--r-- 1 katsuhiro katsuhiro 894 2009-04-08 21:59:33.965953865 +0900 config/codeset.m4 -rw-r--r-- 1 katsuhiro katsuhiro 1394 2009-04-08 21:59:33.977953882 +0900 config/getline.m4 (... 中略 ...) -rw-r--r-- 1 katsuhiro katsuhiro 733 2009-04-08 21:59:34.005955390 +0900 config/strverscmp.m4
一方、サーバではナノ秒の部分にも数値が設定されており、どのファイルも異なる更新時間です。
どうやらデスクトップとサーバではファイルの更新時刻が違うらしいことがわかりました。何が原因かというと、実はファイルシステムが違っていたのです。
デスクトップで使用しているReiserFSやext3では、更新時間のナノ秒部分に常に0を代入します。対してサーバで使用しているXFSでは、更新時間のナノ秒部分まできっちり時間を設定します。
結果、ReiserFSやext3上では同時刻と判断されmakeに無視されるようなファイルも、XFS上では更新時刻が異なると判断され、makeがあちこちのファイルを更新して回る現象が起きてしまうわけです。
おそらくtarなどはアーカイブの展開時にutimeで更新時刻を秒単位で上書きしているはずです。XFSに対して更新時刻を秒単位でいじると、同じ時刻に設定したつもりでも、ナノ秒部分が残ってしまって異なる時刻と判断される、なんてことが起きている可能性がありますね。これは追々調べたいと思います。
デスクトップとサーバではファイルシステムが違うせいでmakeの動作が変わることがわかりました。が、問題はそこではなくて、きちんとコンパイルできないのはsedが悪いのであって、ファイルシステムのせいではありません。本来、ReiserFSでもXFSでもコンパイルできないといけないはずです。
しかしコンパイルで問題が出るのは大抵GNU autotoolsやGNU gettextですから、100%sedが悪いとも言えません。こやつらはバージョン間で仕様がメチャクチャに変わりまくるので、ちょっとバージョンが違うとトラブルが起きます(※2)。
結局、悪いのは誰なのか良くわかりません。長々書いたわりに歯切れが悪い…。
(※2)バージョン間の差を理解してさっと直せれば良いのですが、GNU autotoolsやGNU gettextの激変する仕様について行くのは至難の業です。
この記事にコメントする
| < | 2009 | > | ||||
| << | < | 04 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| - | - | - | 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | - | - |
wiki
Linux JM
Java API
2002年
2003年
2004年
2005年
2006年
2007年
2008年
2009年
2010年
2011年
2012年
2013年
2014年
2015年
2016年
2017年
2018年
2019年
2020年
2021年
2022年
2023年
2024年
2025年
過去日記について
アクセス統計
サーバ一覧
サイトの情報合計:
本日: