〜2002年6月下旬〜
The changes include extensions to the runtime supplied by MSVCRT.DLL in a static lib called libmingwex.a. These extensions include some C89 and C99 wide character functions, floating point environment functions (declared in fenv.h), floating point classification functions and macros, the inttypes.h format conversion macros, stubs for some MSVCRT.DLL underscored functions that are now part of C99 std, and a replacement for fseek and fwrite that are safer on W9x. It also contains the POSIX dirent functions, which have been removed from libmingw.a and added to libmingwex.a. The ISO C extensions are visible by default. To remove them, define __NO_ISOCEXT To use these functions, you will need to explicitly add -lmingwex to your command line. In future releases of GCC, libmingwex.a will become a system lib added automatically by specs.
この変更でisinfとかが#defineされるようになった。 win32/win32.hで
extern int isinf(double); extern int isnan(double);
としてるためMinGWではエラーになる。#ifdef .. #endifで囲むのは簡単だ。 でもlibmingwex.aもlinkしなきゃいけないとなると、 そのライブラリの有無をチェック必要があってちょっと面倒。 というわけで-D__NO_ISOCEXTとした。libmingwexはGCCで対応してからでもいいでしょう。というか忘れないように。 ついでに-D__MSVCRT__はGCCのspecsで定義されてるので削除。 というのが昨日のcommit内容。
patchを見るとCygwinのlibtoolでlibtoolizeし直しになってる。 つまり、libiconvやexpatで使われてるlibtoolが古いってことなんだろう。
更新。ところどころ
cd: can't cd to ./lib
というのが出るが、特に問題はないようだ。 web page を見ていると
28 May 2002, Native uClibc/gcc-3.1 toolchain
というのが気になった。実は以前挑戦して失敗しているので。
いつのまにか 日本語のガイド が用意されてる。でもapacheの設定が足りないらしくtext/plainになってしまう。 usage.html.ja.jisならいいのか?
久し振りにuClibcでコンパイルしてみると
compiling socket Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature. But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry, you cannot compile IPv6 socket classes with broken these functions. You can try --enable-wide-getaddrinfo.
となった。メッセージの通り--enable-wide-getaddrinfoを指定しても、 状況は変わらない。ext/socket/extconf.rbが
$getaddr_info_ok = false if !enable_config("wide-getaddrinfo", false) and try_run(<<EOF) ... EOF $getaddr_info_ok = true end if $ipv6 and not $getaddr_info_ok print <<EOS Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature. But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry, you cannot compile IPv6 socket classes with broken these functions. You can try --enable-wide-getaddrinfo. EOS exit end
となっているので$getaddr_info_okがtrueにならない。解決策としては
メッセージをYou can try --disable-ipv6.にする --enable-wide-getaddrinfoだったら$getaddr_info_okは無条件にtrueに
のどちらがいいかな? というよりAF_INET6の存在でIPv6かどうかを判断してるのがゆるすぎるのかもしれない。 そこをなんとかすれば
default_ipv6 = /cygwin/ !~ RUBY_PLATFORM
もなくせるんだけど。
--enable-wide-getaddrinfoに関しては
$getaddr_info_ok = false if !enable_config("wide-getaddrinfo", false) and try_run(<<EOF)
を
$getaddr_info_ok = enable_config("wide-getaddrinfo", false) if !$getaddr_info_ok and try_run(<<EOF)
にすればいい気がしてきた。 でも、こうしてみるとなぜかgetaddrinfoはあることになるなあ。 ということはこの変更じゃだめだ。 あ、そもそもuClibcのIPv6対応をonにしてないから、 実際に実行してみるとエラーになるのが原因だ。 ConfigのINCLUDE_IPV6をtrueにして作り直し。やっぱそうか。
結論としては今のままだと--enable-wide-getaddrinfoは機能してないので、
if $ipv6 and not $getaddr_info_ok and not enable_config("wide-getaddrinfo", false)
てな感じの変更が必要だ。と、まとめたかったんだが、まとまらない。 実際にgetaddrinfo.cをコンパイルしてみるとエラーになる。
getaddrinfo.c:483: structure has no member named `s6_addr8'
USAGIを確認してみる。
% bzip2 -dc usagi-linux24-s20020610-2.4.18.diff.bz2 |grep s6_addr8 % bzip2 -dc usagi-tool-s20020610.tar.bz2 |grep s6_addr8 %
ないねえ。今はs6_addrを使えってことだろうか。 itojunさんはたしかNetBSD使いだよね。 NetBSD 1.5を立ち上げて/usr/include/netinet6/in6.hを見てみる。
#define s6_addr __u6_addr.__u6_addr8 #ifdef _KERNEL /*XXX nonstandard*/ #define s6_addr8 __u6_addr.__u6_addr8 #define s6_addr16 __u6_addr.__u6_addr16 #define s6_addr32 __u6_addr.__u6_addr32 #endif
なるほど。こっちでは定義されてる。 とは言うものの#ifdef _KERNELだし、やはりs6_addrを使うべきだろう。 というかこれじゃNetBSDでは--enable-wide-getaddrinfoはエラーになるな。 _KERNELはdefineされてないし。 ま、*BSDにはKAMEが入ってるからそんなことする必要ないけど。
出たけど、すぐに次が出そうだ。
更新。というわけで普通のユーザでmake installしてみる。
そうか。w3mならvで切り替えられるんだな。 hoge.html.inのようなconfigure対象ファイルを見るときに、 一々-T text/htmlとするよりは便利だ。
ruby-talk MLの流量が少なすぎる。news gatewayが止まってる?
結局のところ$ipv6_okが真のときに--enable-wide-getaddrinfoしても
getipnodebyaddr() getipnodebyname() freehostent()
が実行時にundefined symbolになり、使えないことが判明。
% LD_LIBRARY_PATH=.:/usr/i386-linux-uclibc/lib ./ruby -r./ext/socket/socket -e0 ./ruby: can't resolve symbol 'getipnodebyaddr' ./ruby: can't resolve symbol 'getipnodebyname' ./ruby: can't resolve symbol 'freehostent__compat' 0: Unable to resolve symbol - ./ext/socket/socket.so (LoadError)
USAGIにはない。しかもuClibcのIPv6対応ってUSAGIそのものだった。 KAMEにはあるはずだから、そこからこの3つを持ってくるか。
それはそれとして
-Wl,-no-undefined
を加えたほうがいいかなあ。
ccache /usr/i386-linux-uclibc/bin/gcc -shared \ -nostartfiles -Wl,-no-undefined \ -L/pub/ruby/uclibc -L/usr/local/lib \ -o socket.so socket.o getaddrinfo.o getnameinfo.o -L. -lruby -lc getaddrinfo.o: In function `get_name': getaddrinfo.o(.text+0x6ea): undefined reference to `getipnodebyaddr' getaddrinfo.o(.text+0x780): undefined reference to `freehostent__compat' getaddrinfo.o(.text+0x7a1): undefined reference to `freehostent__compat' getaddrinfo.o: In function `get_addr': getaddrinfo.o(.text+0x8ca): undefined reference to `getipnodebyname' getaddrinfo.o(.text+0x9f6): undefined reference to `freehostent__compat' getaddrinfo.o(.text+0xa5f): undefined reference to `freehostent__compat' getnameinfo.o: In function `getnameinfo__compat': getnameinfo.o(.text+0x1bd): undefined reference to `getipnodebyaddr' getnameinfo.o(.text+0x1fa): undefined reference to `freehostent__compat' getnameinfo.o(.text+0x213): undefined reference to `freehostent__compat'
とLinuxでもリンク時にわかる。 freehostentに__compatをつけてるということは、 やっぱ、ここで用意すべきだな、きっと。 というわけで明日はKAMEを調べよう。 あ、gai_strerrorにも__compatをつければuClibcのad-hocな対応は要らないじゃん。
天泣記 を見てて、そうかコメントもあったねと対応してみた。 comment()を追加すればいいようだ。 tidyのように謎の空行は入らないし、よさげ。
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="@*|*|text()|comment()"> <xsl:copy> <xsl:apply-templates select="@*|*|text()|comment()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
実はsnapshotsを使ってるときから気づいていたんだけど、 1.3.11のfseekがなんか変だ。splintがエラーになる。
Tests: Checking help... Checking abstptr... Checking abstract... Checking alias... 1a2,8 > bool.h:4:1: *** Internal Bug at llerror.c:1866: macrocache.c:257: Check Failed: > fseek (s_macFile, 0, SEEK_CUR) == 0 [errno: 2] > *** Last code point: transferChecks.c:4395 > *** Previous code point: transferChecks.c:3978 > Possible system error diagnostic: : No such file or directory > *** Please report bug to splint-bug@splint.org *** > (attempting to continue, results may be incorrect)
メッセージに従いソースを追ってみると、fseekがなぜかエラーを起こしてるらしい。 fseekといえばbinmode vs. textmodeに違いないと思い面倒だから放っといたんだけど、 Rubyでも
% ruby -e 'open("foo", "wb"){|fh|p fh.seek(0, File::SEEK_CUR)}' -e:1:in `seek': No error - "foo" (Errno::E000) from -e:1 from -e:1:in `open' from -e:1
なのでCygwinのソースを見てみる。 場所はnewlib/libc/stdio/fseek.cだ。
fflush(fp); /* may adjust seek offset on append stream */ if (fp->_flags & __SOFF) curoff = fp->_offset; else { curoff = (*seekfn) (fp->_cookie, (fpos_t) 0, SEEK_CUR); if (curoff == -1L) _funlockfile(fp); return EOF; }
なるほど。Pythonじゃないんだから、これじゃだめだ。 _funlockfile(fp);を追加したときに{}を忘れたようだ。 ここで必ずEOFを返してしまう。しかもこの後の処理も実行されないからかなりまずい。 newlibのREADMEを見たらnewlib@sources.redhat.comへ送れということなので、 パッチ作ってバグ報告したら半日ほどして、
Applied. Thanks.
が来た。というわけで次のCygwinのリリースに間に合ったようだ。
上の変更でsplintがちゃんと動くかどうか確認するためにcygwin自体をmakeしてみる。 ついでだからGCC 3.1でmakeしよう。 実は会社のクロスの環境はGCC 3.1にしてあったりするんだが、 いつも通りの手順で問題なくnew-cygwin1.dllはできた。 これでsplintを試すとめでたくok。GCC 3.1でも大丈夫のようだ。
動かなかったlhaも動くようになった。 ひょっとして これ も、No errorってあたりからして同じかもしれない。 すぐに1.3.11-4が出るとは思うけど、 fseekでSEEK_CURを使っているソフトは要注意だ。
Cygwin MLでも 報告 があったけど、Cygwin 1.3.11にしたらコマンド起動のもたつきがかなり気になる。 タスクマネージャで見てもCPU利用率は0%のままなので、 何かを待っているようだ。 なにしろどんなコマンドも10秒ほど待たされるので使いものにならん。 と思ったら別のマシンでは最初のzsh起動時は待たされたが、 その後は順調だ。うーむ。違いはというとbashとzshだな。そうか。 bashから起動すると遅くてzshだと問題ないんだ。 shとtcshも試したが問題なし。bashだけ秘孔を突いたらしい。 あまり使わないからいいけど。
見るの忘れてた。後日。
そうか。確かにおいらもdomainにlogonしてる。 やめてもいいんだけど、ファイルの所有権の変更が面倒だなあ。
ってだれ?
更新。
面白そう。setopt HIST_IGNORE_ALL_DUPSしてるのでmakeはもっと上位にいくかもしれない。
% ruby -pe 'gsub(/^.?+;| .+$/,"")' ~/.zshhist |sort |\ uniq -c |sort -r |head -20 2605 ls 2486 less 2065 cd 1514 grep 1157 vi 1081 mv 808 tar 766 ruby 732 sudo 715 rm 625 make 576 cp 469 w3m 359 locate 261 man 245 echo 240 mkdir 224 cat 216 diff 178 wget
使ってるコマンドはほとんど同じだ。
知らなかった。
確かにgccではエラーにならない(PR#270)。
% echo 'void foo(){ int i = i; }' >foo.c % gcc -Wall -c foo.c %
splintにかけてみる。
% splint foo.c Splint 3.0.1.6 --- 18 Jun 2002 foo.c: (in function foo) foo.c:1:21: Variable i used before definition An rvalue is used that may not be initialized to a value on some execution path. (Use -usedef to inhibit warning) Finished checking --- 1 code warning
うーむ。warning扱いか。
Cygwin 1.3.11-3とOpenSSHの更新で設定が混沌としていていまいちよくわからず。 とりあえず1.3.10に戻すか。
MinGWが入ってなかったので追加。
--- ext/gettext/gettext/extconf.rb.orig 2002-06-29 18:52:27.000000000 +0000 +++ ext/gettext/gettext/extconf.rb 2002-06-30 13:50:29.000000000 +0000 @@ -13,3 +13,3 @@ -if RUBY_PLATFORM =~ /cygwin|mswin32|bccwin32/ +if RUBY_PLATFORM =~ /cygwin|mingw|mswin32|bccwin32/ have_header 'windows.h'