link もっと前
   2009年 4月 8日 -
      2009年 4月 8日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

同じはずの環境

サーバでプログラムを make すると、挙動が違うことに気づきました。

例えば sed-4.1.5 ですと、デスクトップの VM 上でコンパイルすると何事もなく成功するのに、サーバでコンパイルすると sed-4.1.5/po 以下の *.po ファイルを更新しようとして失敗し、コンパイルがコケてしまいます。

デスクトップ、サーバともに Debian GNU/Linux 5.0(Lenny)ですから、コンパイラを始めとしたツールの差はなく、環境変数も同じですし、全く同じソースを利用しています。にも関わらずコンパイルに成功したり、しなかったりするのはなんなのでしょうか?

違いを追え

どうやら使っているツールや環境変数、ソースコードまで同じなのに動作が異なるという現象が起きうるようです。

まずはオーソドックスな手順(※)でコンパイルを進めてみて、違いが出る場所を調べました。configure のログは違いなしですが、make のログは一行目から既に違っています。

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)に入って、コンパイルが始まります。

make 実行結果(サーバ)
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 ターゲットが適用されるか、されないかが異なるためです。

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 の激変する仕様について行くのは至難の業です。

[編集者: すずき]
[更新: 2010年 7月 23日 23:32]
link 編集する

コメント一覧

  • すずき 
    1つ目の「更新時刻(サーバ)」は間違い。
    「更新時刻(デスクトップ)」です。
    あとで訂正します。 
    (2010年07月23日 10:56:35)
  • すずき 
    訂正完了。 
    (2010年07月23日 23:33:43)
open/close この記事にコメントする



link もっと前
   2009年 4月 8日 -
      2009年 4月 8日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 11/11 11:44

カレンダー

<2009>
<<<04>>>
---1234
567891011
12131415161718
19202122232425
2627282930--

最近のコメント 5件

  • link 19年09月01日
    すずき 「私も正直びっくりです。間違って違う製品を...」
    (更新:09/04 23:39)
  • link 19年09月01日
    hdk 「車向けの製品の中でも、車載コンピューター...」
    (更新:09/02 23:20)
  • link 19年07月18日
    hdk 「あっ、AAMはマニュアルのオペレーション...」
    (更新:07/25 00:02)
  • link 19年07月18日
    すずき 「AAM(ASCII Adjust AX ...」
    (更新:07/24 22:22)
  • link 19年07月18日
    hdk 「加算減算は符号のありなしどちらも命令が同...」
    (更新:07/24 07:25)

最近の記事 3件

link もっとみる
  • link 19年11月07日
    すずき 「[独自の apt サーバー - その 6 - ソースコードパッ] ...」
    (更新:11/11 11:44)
  • link 19年08月29日
    すずき 「[独自の apt サーバー - その 5 - 複数のセクション] ...」
    (更新:11/08 00:41)
  • link 19年08月13日
    すずき 「[独自の apt サーバー - その 4 - まとめ] 独自の a...」
    (更新:11/08 00:41)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報