それと、これは http://www.darwinfo.com のメーリングリストアーカイブでも議論されていたが、MacOS X の iostream には flush が効かないという問題がある。次の例で再現できる。
$ cat test.cxxここで "Parameter ?" と言って欲しいのだが、何も言わない。何か入力するとその時点で出力される。これでは使いものにならない。
#include <iostream.h>
int main() {
double x;
cout << "Parameter ? " << flush; // this does not work
// cout.flush(); // this does not work either
// fflush(stdout); // though this works OK
cin >> x;
return 0;
}
$ c++ test.cxx -o test
$ ./test
問題の flush を含む iostream.o は libstdc++.a に含まれ、そのソースは gcc-3/libio/iostream.{h,cc} であるが、flush の実体をたどっていくと gcc-3/libio/streambuf.cc の中に定義されている streambuf::sync() に行くつく。ところが、この streambuf::sync() は retrun 0 しているだけなのである。どうするのが正しいか不明だが(意図的にこうしてある可能性もある)、とりあえず副作用を最小限にすると言う意味で、streambuf::sync() を変更するのでなく、iostream::flush() に次のような変更を加えた。
--- gcc-3/libio/iostream.cc.ORIG Wed Aug 9 09:30:13 2000つまり、普通の C の fflush を使うのである。こうすることで一応上の問題は解決した。ただし、これには副作用がある可能性もあるのであくまで実験版と言うことで、libstdc++.a.exp.tar.gz として置いておく。これをトップディレクトリーで展開すると
+++ gcc-3/libio/iostream.cc Wed May 9 04:39:58 2001
@@ -940,11 +940,16 @@ostream& ostream::flush()
{
- #ifdef MACOSX
+#ifdef MACOSX
_IO_init_global_stdio ();
#endif
+#ifndef MACOSX
if (_strbuf->sync())
set(ios::badbit);
+#else
+ if (fflush((FILE *)_strbuf))
+ set(ios::badbit);
+#endif
return *this;
}
/usr/lib/gcc/darwin/2.95.2/libstdc++.a.expができるので、同じディレクトリーにある libstdc++.a と置き換えて使う。オリジナルはバックアップしておくのが無難。それとあくまで実験版であるのでいつものように使う場合には自己責任で(2001/05/10 追記:これですが不具合を生ずる場合があることが判明しましたので封印します。当面アプリケーション側で fflush(stdout) として逃げる。いずれにせよ、iostream.o はいろいろなところに既に静的にリンクされているに違いないので不整合を起こす可能性は高い)。
それと、この実験版 libstdc++.a を作っていて気づいたのだが、MacOS X を 10.0.02 にアップデートしてから libtool の挙動がおかしい。これはわたしのところだけの問題だろうか?例えば、ranlib libstdc++.a とかすると、一部の c++ のアプリケーションのリンクで undefined symbols が出るようになってしまう(注意:ranlib は libtool にシンボリックリンクされている)。むやみに libtool を使うと危険。libstdc++.a.exp をわざわざ tarball にしたのはそのため。コピーするなら cp -p を使う事。同じ注意はオリジナルの libstdc++.a をバックアップする場合にも必要。
今までにコンパイルしたMacOS X Release 用の rpm については、 spec ファイル、パッチ、ソース
RPM、バイナリー RPM それぞれについて
SPECS、
SOURCES、
SRPMS、
RPMS
に対応するものが置いてある。RPMS 以下の ppc はマシン依存な RPM 、noarch
はマシン非依存な RPM の置き場所である。バイナリーのみの RPM および Tar
Ball のみのパッケージの場合には、ソースおよびパッチは
src
に、また、Tar Ball は tgz
にそれぞれ置いてある。新しいものは ~fujiik/macosx/10.0.X/ 以下にある点に注意(~fujiik/macosx
直下のものは Public Beta 用の古いもの)。 いつものように使う場合は自己責任で。
Back
to Keisuke Fujii's MkLinux/LinuxPPC Life