Gauche:LargeFileSupport

Gauche:LargeFileSupport

Shiro (2007/11/08 17:39:10 PST): いまどき、2G超のファイルを扱えないなんてださいよね。 だのになぜ0.8.12 on Linuxでは未だ対応していないかというと…

「混ぜると危険」問題

LinuxやSolarisなどは過去との互換性のためデフォルトでoff_tが32bitになってるが、 コンパイル時に適当なプリプロセッサシンボルを定義してやればoff_tが64bitになり、 off_tを取るシステムコール呼び出しも64bit版を呼ぶようになる。 なのでgoshのことだけ考えるならLFS対応はすぐできる。

ただ、LFS対応でコンパイルされたlibgaucheと、LFS未対応でコンパイルされた 他のライブラリとを一緒に使おうとすると、まずいことが起きる。 ヘッダの宣言に現れるoff_tが、コンパイル済みバイナリのどちらかと 食い違ってしまうからだ。

一番安全なのはこういう対応:

  1. libgaucheの外部APIには一切off_tを使わない (今は少しだけoff_tを使ってるAPIがある)
  2. libgaucheおよびext/* 以下のコンパイルの時のみLFS対応でコンパイルする

後者は、<gauche.h>をインクルードして使う人にはLFS対応フラグを見せないってこと。 つまりgauche/config.hやCFLAGSにLFS対応フラグを入れられない (CFLAGSはgauche-configに埋め込まれて拡張ライブラリのコンパイルに 使われるので)。

でもそれをやろうとすると面倒なんだよなー。libgaucheとext/*の時だけ使う フラグを別に管理しないとならないし、autoconfのAC_SYS_LARGEFILEにも 頼れない。

次善の策としてはLFS対応フラグだけを含んだ別のヘッダファイルを生成しといて、 libgaucheとext/*のソースだけはそれをincludeする、という方法。 これならAC_SYS_LARGEFILEも使えるし、CFLAGSをごにょごにょいじる必要もない。 けれどもなんかそういう例外的なヘッダを持つのも気持ちが悪い。 (新しくext/*を追加したときに追加を忘れそうだしな)。

こうやって完全分離してしまった場合、 外部の拡張ライブラリのLFS対応はそれぞれの実装者に任されることになる。 LFS未対応のライブラリと組み合わせたい拡張にとってはそれは都合が良いのだけれど、 virtual portなどを実装しようという場合はライブラリ実装者がLFS対応を 気にしなくちゃならないので不便な感じだ (virtual portのseek関数ポインタが ファイルオフセットを扱う。今はoff_tを受け渡しているが、完全分離を 目指すならここをScmInt64などに統一することになるだろう。 そうするとライブラリ実装者側で、ScmInt64 <-> off_t 変換をちゃんと やらなくちゃならなくなる。全てのケースに対応するのは結構面倒。)

さてどうしようかな。 既存のライブラリの多くがLFS対応でコンパイルされてるんだったら もう強引にconfig.hにLFSフラグを入れちゃうのが一番簡単なんだが…

困った時は他を真似してみる

Rubyはconfig.hに入れてるようだ: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/44114

考えてみたら

_FILE_OFFSET_BITS以外にもgauche/config.hは名前空間 汚染しまくりなわけで (configureオプションに結果が影響されるような HAVE_* 系の 定義値は、他のライブラリが期待しているものと異なる可能性がある)、 他ライブラリとの安全な共存を考えるならそもそもgauche/config.hを 外に見せるべきではないのであった。

であるからして、今のところは _FILE_OFFSET_BITS などはconfig.hに 突っ込んでおき、問題が出たらconfig.hを隠すことの方を考えることにする。 と言ってもそれがレアケースならその都度ブリッジコードを書いちゃうという 対応で十分かもしれないが… (つまり、ライブラリfooとlibgaucheで これらのプリプロセッサシンボルに食い違いがある場合、クライアントコード 中でfoo.hとgauche.hを同時にインクルードすることはせず、 どちらの型にも依存しないスタブルーチンを一段噛ませるようにする。)


Last modified : 2007/11/09 09:27:03 UTC