〜2002年1月下旬〜
i386-cygwinとかi386-msdosdjgppとか書くのが面倒になってきたので、 って一年も経ってるのに今頃かよ、cygwin,mingw,djgppでもいけるようにした。
ifneq (,$(findstring $(TARGET),cygwin)) TARGET=i386-cygwin endif ifneq (,$(findstring $(TARGET),mingw)) TARGET=i386-mingw32 endif ifneq (,$(findstring $(TARGET),djgpp)) TARGET=i386-msdosdjgpp endif
PACKAGE, VERSION, TARGETが指定されてないときは、 wordsを使えば一度にチェックできてよさげだ。
ifneq ($(words $(PACKAGE) $(VERSION) $(TARGET)), 3) $(error You must set PACKAGE, VERSION and TARGET.) endif
最近雑誌やWeb上で
-rw-r--r-- 1 watanabe ruby 0 1月 21 01:08 foo
というls -lの結果がよく目立つ。なぜ「21日」とならないんだろう? 古めのruby-1.2.6/ChangeLogは
-rw-r--r-- 1 watanabe ruby 90643 6月 21 1999 ChangeLog
と「年」もない。昔はちゃんと表示されてたはず。 fileutils.moがまずい?
ふだんLC_TIME=C, LC_MESSAGES=Cしているおれにはどうでもいい話ではあるが。
-g '*.{rb,so}'は試したんだけど、-g '*.(rb|so)'ってのは思い付きませんでした。 ものすごく意外です。というわけで
_path_files -W dirs -g '*.(rb|so)' -/
としよう。
毎度お馴染のどたばたで1.3.8になった。 まだミラーサイトには来てないので試してない。 アナウンスにも書いてあるように1.3.7のcygwin1.dllは、 regfreeがexportされてないのでlftpとか動かなくなって、 makeし直したなんて内緒だ。
実は1.3.7の
- Create special versions of import library with only appropriate symbols for libpthread.a, libm.a, and libc.a. (Ralf Habacker, Christopher Faylor)
が気になっていたんだけど、これも明日要確認だな。
今回はこんな感じで。
% tar xfvz glibc-2.2.4.tar.gz % mv glibc-2.2.{4,5} % cd glibc-2.2.5 % bzip2 -dc ../glibc-2.2.4-2.2.5.diff.bz2 |patch -p1 % tar xfv ../glibc-linuxthreads-2.2.5.tar.bz2 --bzip2 % mkdir linux; cd linux % CC='/usr/bin/gcc -pipe' \ CFALGS=-Os \ ../configure \ --prefix=/usr \ --enable-add-ons % make execv: Permission denied .../glibc-2.2.5/linux/sunrpc/rpcgen: C preprocessor failed with exit code 1
エラーになってしまった。うーむ。
1.3.8を取ってこようと思ったらすでに1.3.9だった。
いまのとこ問題なし。pdnsd-ctlを使うとDynamic DNSみたいなことができる。
% sudo /usr/local/sbin/pdnsd-ctl add a 192.168.1.100 hoge.localdomain Opening socket /var/cache/pdnsd/pdnsd.status. Succeeded % ruby -rresolv -e 'p Resolv.getaddress("hoge.localdomain")' "192.168.1.100"
永続化はできない。立ち上げ直すと忘れてしまう。
やはりoff-line時に使えるDNSがあると便利だ。
また遅れてる。[ruby-list:33478]から[ruby-list:33481]が来ない。
logger.rbしかインストールされないのでちょっと不安になる。 それはそれとしてパッケージを作る。
あ、東風だ。
そもそもチェックするだけならrubyすら必要ないのに、 なぜresolv.rbかと言えば、単に このtimeout を思い出したから。でもdnscacheを使ってたときは試すのを忘れてたんだった。
流量が多いからruby-talkを分割しよう案が出てる。 その中にはやはり
ruby-dev ruby-ext
という名前も挙がっている。 そろそろ日本語メーリングリストは-jaとかつけないとまずそう。
なぜかexecv: Permission deniedになる件は全然解決しないんだけど *1、 とりあえず別のPentium!!! 800MHzなマシンで実行してみると30分で無事make終了。 うーむ。全くもって解決しない。
そのままtarballを作ってこのマシンへ転送して試す。
% mkdir ~/glibc-2.2.5; cd ~/glibc-2.2.5 % tar xfvz glibc-2.2.5-bin.tar.gz % ls etc lib sbin usr % mkdir bin % cp /bin/bash bin % ldd =bash libncurses.so.5 => /lib/libncurses.so.5 (0x4001a000) libdl.so.2 => /lib/libdl.so.2 (0x4005b000) libc.so.6 => /lib/libc.so.6 (0x4005e000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) % cp /lib/libncurses.so.5 lib % sudo chroot ~/glibc-2.2.5 /bin/bash zsh: illegal hardware instruction sudo chroot (J~(B/glibc-2.2.5 /bin/bash
む?glibcってそんな最適化オプションまでつけるのか。 しかたなくconfigure時にi586-pc-linux-gnuを指定してもう一度やり直し。
% sudo chroot (J~(B/glibc-2.2.5 /bin/bash bash-2.04#
よさそう。週末にでも入れ換えよう。あう、bashを更新するの忘れてる。
% sbash --version GNU bash, version 2.05.0(1)-release (i586-pc-linux-gnu) Copyright 2000 Free Software Foundation, Inc. % ldd =sbash not a dynamic executable
static版を作っただけだったんだ。 diet libc版ashがあるからsbashはもう要らないな。
% ls -l /bin/ash /bin/sbash -rwxr-xr-x 1 root root 78808 Jan 20 17:56 /bin/ash -rwxr-xr-x 1 root root 561044 Aug 11 18:25 /bin/sbash
/bin/shもashにしようかなあ。 /etc/rc.d/あたりがbashに依存してなければいいんだけど。 でも動かなければ#!/bin/bashに書き換えちゃえばいいだけの話か。
まだ遅れてる。もう10日も経つというのに。 いい加減rimを見限るべき?
大宮駅で本を売ってた。
案の定きちんと立ち上がらない。次はglibc 2.2.5も待っているというのに。 ってそれはどうでもいい。やはり旧環境を残しといて正解だ。
メッセージを見てるとread-onlyのままつき進んでいるようだ。 /etc/rc.d/rc.Sでread-only filesystemかどうか判断してるんだけど、 ashだとこの手は使えないらしい。
READWRITE=no if echo -n >> "Testing filesystem status"; then rm -f "Testing filesystem status" READWRITE=yes fi
ifのところは、bashなら
/etc/rc.d/rc.S: Testing filesystem status: Read-only file system
と表示して先に進むが、ashだと
/etc/rc.d/rc.S: cannot create Testing filesystem status: read-only file system
と表示してrc.S自体が終了してしまう。 rc.Sでrwでremountするので、read-onlyのままなんだな。 ここは#!/bin/bashとしよう。 最初から存在してるスクリプトでは結局これだけだった。 残り2つは後からインストールしたもの。
/etc/rc.d/init.d/fcronで
start-stop-daemon: not found
と表示される。これは
elif start-stop-daemon -V > /dev/null 2>&1; then
がなぜかredirectされないため。 typeを使って存在をチェックしたほうがまだいいのかもしれない。 どうせ存在しないからコメントアウト。
/etc/rc.d/init.d/vmwareで
local: not found
が出てる。vmwareはlocalだらけなので#!/bin/bashとする。
これでいいようだ。
後日どころか 即日リンク を返しているんですけど?
Ruby 1.6.6 (2001-01-25)でconfigure.inを変更したから、 configureし直したわけだが、何かが変。 /bin/shをashにしたからbashとashの挙動の違いであることは確かだ。
例えばmingw32版はそもそもconfigure自体が失敗する。
configure: error: cached CC is different -- throw away ./config.cache (it is also a good idea to do 'make clean' before compiling)
configureに与えるオプションがいっぱいあって、 それをシェルスクリプトにしてるので以前と違いはないはず。 config.cacheを見てみると
ac_cv_prog_CC=${ac_cv_prog_CC=$'i686-pc-cygwin-gcc -bmingw'}
となっていた。む?この$はいったい何?早速実験だ。
% bash -c 'a=$"foo bar";echo $a' foo bar % ash -c 'a=$"foo bar";echo $a' $foo bar
なるほど。これが原因か。zsh、pdkshでも試してみよう。
% zsh -c 'a=$"foo bar";echo $a' $foo bar % ksh -c 'a=$"foo bar";echo $a' $foo bar
どうもbashの形勢不利だな。 bashだとconfig.cacheを保存時に$をつけて、読み込む時に$を取るので、 なんとなく辻褄が合ってしまっているのか。
config.cacheを消してconfigureすると
ac_cv_prog_CC=${ac_cv_prog_CC='i686-pc-cygwin-gcc -bmingw'}
となった。やはりあの$はどこから出てくるのか気になる。
予報通り夜に雪となったが、2,3時間ほどでまた雨に。
ソースを見てみる。ははは。
#define IF if( #define THEN ){ #define ELSE } else { #define ELIF } else if ( #define FI ;}
各ファイルにはちゃんとS. R. Bourneと名前がある。
ダイアルアップで6MB弱は痛かったけど、取ってきた甲斐があったなあ。おもしろい。
ftp://minnie.tuhs.org/UnixArchive/4BSD/Distributions/4.2BSD/
のsrc.tar.gz。
早速makeしてみるとエラーだらけ。 1983年当時のコンパイラでは許されていたのか。 とりえずコンパイルエラーだけは 直して みたが、SEGVになる。
(gdb) run Starting program: /home/watanabe/0201/bin/sh-eban/sh Program received signal SIGSEGV, Segmentation fault. 0x804841a in addblok (reqd=28) at blok.c:63 63 pushstak(0);
pushstakは
#define pushstak(c) (*staktop++=(c))
のようマクロになっている。
(gdb) p staktop $1 = 0x4c49414d <Address 0x4c49414d out of bounds>
これは"LIAM"だな。逆から読むと"MAIL"だ。 どうもalloc()がまずいようだ。setbrk.cを見るとsbrk(2)してる。 mode.hを
-union { int _cheat;}; -#define Lcheat(a) ((a)._cheat) +#define Lcheat(a) *((int *)&(a))
としたのが間違いだと思うんだけど、 そもそもこのunionが今じゃ考えられない使い方をしてるしなあ。
unionにしろstructにしろcastしないで使えてたのが不思議だ。
作っておいた tarball を展開する。 いつものように他のktermでsuして非常事態に際して待機しておく。
% sudo tar xfUvz glibc-2.2.5-bin.tar.gz -C / % sudo ldconfig % ruby -v ruby 1.6.6 (2002-01-25) [i386-linux]
よさそう。rebootしてみる。特に問題なし。 ここで時計を見てなんか変だと気づいた。UTCになってる。
% date Sat Jan 26 15:24:57 Local time zone must be set--see zic manual page 2002
ふーむ。
% man zic man: No such file or directory zsh: segmentation fault man zic
あれ?manが動かなくなった。とりあえずtime zoneを直そう。
% ls -l /etc/localtime lrwxrwxrwx 1 root root 29 Jan 26 14:46 /etc/localtime ->\ ../usr/share/zoneinfo/Factory
これか。
% sudo ln -sf /usr/share/zoneinfo/localtime /etc/localtime % date Sun Jan 27 00:28:52 JST 2002
okだ。
これは何がないと言ってるのかな?ltraceしてみる。
perror("man") = <void> fprintf(0x08050d18, "Failed to open the message catal"... <unfinished ...> --- SIGSEGV (Segmentation fault) ---
perrorはNo such...だな。その後のfprintfは表示されてないからここでSEGVか。 unfinishedが非常に怪しいが、わからん。ソースを手に入れよう。 日本語 man 環境の設定 を見てman-1.5g.tar.gzとman-1.5g-ja2.diff.gzを入手。 そのページの通りにインストールするとSEGVはしなくなった。 あ、これじゃ原因がわからないな。ま、いいか。
結局存在しないmanualを指定するとNo such...になるようだ。 でもzicはあるんだけどなあ。
% man foo man: No such file or directory Failed to open the message catalog man on the path NLSPATH=<none> No manual entry for foo
これを表示したかったのか。場所はsrc/gripes.cで、
s = getenv("NLSPATH"); lg = getenv("LANG"); if ((s || lg) && (!lg || strcmp(lg, "en"))) { perror(mantexts); fprintf(stderr, "Failed to open the message catalog %s on the path NLSPATH=%s\n\n", mantexts, s ? s : "<none>");
これじゃLANGをenにしない限り必ず表示されるね。 あまり意味があるとも思えないな。-DNONLSを加えよう。
% man foo No manual entry for foo
これでよしとする。
あの実験 は何の役にも立ってなかったわけですね。 一番外側を""にするとlogin shellが展開しちゃうと思ってああしたわけだけど、 それが裏目ってしまったか。
% bash -c "a=$'foo bar';echo \$a" foo bar % zsh -c "a=$'foo bar';echo \$a" foo bar % ash -c "a=$'foo bar';echo \$a" $foo bar % ksh -c "a=$'foo bar';echo \$a" $foo bar
うーむ。どうもpdkshはそれほどkshと互換性がないようだ。
というわけで 本家KornShell を試してみよう。
INIT と ast-ksh のSOURCEをダウンロードしてみたがどうもよくわからない。
% mkdir ast; cd ast % tar xfvz ../INIT.2001-10-31.tgz % tar xfvz ../ast-ksh.2001-10-31.tgz % export PACKAGEROOT=$PWD % export INSTALLROOT=$PACKAGEROOT/arch/`bin/package` % bin/package make CC=gcc CCFLAGS=-Os (snip) +zsh:1> mamake -r */* -k install ksh93 CC=gcc CCFLAGS=-Os zsh: command not found: mamake mamake: *** exit code 1 making all (snip)
うーむ。PATHの問題かと思って"."を足してみてもだめ。 ちゃんとbin/package helpを読もう。やっぱりわからん。 zshが出てくるってことは環境変数SHELLか?
% SHELL=/bin/sh bin/package make CC=gcc CCFLAGS=-Os
あ、いけた。どうもそういうことらしい。 bin/packageには#!がないのからzshが実行してしまうのか。 bin/packageはzshには対応してないんだな。 なぜ#!/bin/shとなってないんだろう? #!/bin/kshを入れるわけにはいかないし、 kshを作っているところだけに意地でも#!/bin/shを入れたくなかったとか。
じゃ
% sh bin/package make CC=gcc CCFLAGS=-Os
でいいじゃんという気がするが、これもなぜか
zsh: command not found: mamake
となる。中でまたシェルスクリプトを呼んでいるのか。
いけたと軽く書いてるけど、 実は1時間経った今、まだsfioを作ってるところだ。kshのコンパイルはまだまだ先らしい。 しらばくしてkshをmakeしにいった。parse error続発だ。なんで止まらないんだ? bashで試そう。
% SHELL=/bin/bash bin/package make CC=gcc CCFLAGS=-Os
同じだ。
FEATURE/options:12: parse error before '/' token
が気になる。arch/linux.i386/src/cmd/ksh93/FEATURE/optionsを見てみると、 なんと
/usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby/1.6/i386-linux /usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6 /usr/local/lib/ruby/1.6/i386-linux .
が間にはさまってるじゃん!びっくりだよ。だれがrubyを実行したんだ? 先頭を見るとsrc/cmd/ksh93/features/options.shが作ったとわかる。
sh -c 'function foo { local bar=0 2> /dev/null || return 1 return ${bar=1} } foo ' && echo "#define SHOPT_ALIASLOCAL 1"
だからfunctionとlocalをサポートしてないとだめなんだ。 ちがうか。localをサポートしてるかどうかを調べてるんだ。 ~/bin/fooに
#!/usr/local/bin/ruby puts $:
というのあってこれが実行されてた。なにかの実験のために置いてたんだろうきっと。 たぶん
PATH= foo
と実行してくれればfooというコマンドがあったりしても問題ないんだけど。 普通はないよね、そんな名前のコマンドは。
% cp =bash ~/bin/sh % rm arch/linux.i386/src/cmd/ksh93/FEATURE/options
してもう一度。ついでにSHELL=/bin/bashにしとく。いいみたい。やっと先に進んだ。
これで試せる。
% arch/linux.i386/bin/ksh -c "a=$'foo bar';echo \$a" foo bar
ああ、満足。って長いよ。
それにしてもでかい。stripしても800KBか。
% ls -l ksh -rwxr-xr-x 1 watanabe ruby 819576 Jan 27 19:22 ksh
インストールはインストールでtsortが必要らしい。
% SHELL=/bin/bash sudo bin/package install /bin ksh tsort: not found package: at least one package name expected
面倒なのでcpしとこう。pdkshは/bin/pdkshに名前を変更。
なるほど。 無限ループしてるようなのでgdbで調べてたんですけど、 確かにfault.cを見るとtrapしてるようですね。 defs.hには
#define MEMF 11
と書かれていて、これはSEGVだし。
ソースを見ただけで結構満足できたし、これはこれでよしとしよう。
更新。eval対応がそろそろ出そうではあるけど。
Ruby-GTK maintainerのNeil Conwayさんに聞かれたときに このパッチ を渡したら
Great! Patch applied.
と言われたので、すでに修正されてるんじゃないかな。
例によってsched O(1)とpreemptをあてる。preemptはrejectしたが、手で修正。
EXPORT_SYMBOL(waitfor_one_page);
は復活してるようだ。
[ruby-list:33539] でなにをcommitしようとしてたかというと、 [ruby-list:33531] を受けて、 以下の断片を追加しようと思っていた。
case "$target_os" in solaris2.[0-6]*);; *) LDSHARED="$LDSHARED -shared";; esac
で、実際にテストしてみると、どうしても-sharedがついてしまう。 この部分の抜き出して実行すればちゃんと意図した通りに動く。 1時間ほどしてautoconfでは[]はquote文字だと気づく。
solaris2.[[0-6]]*);;
としないといけないんだよね。
このテスト自体はsolarisじゃなくても
% ./configure --target=sparc-solaris2.5 % ./configure --target=sparc-solaris7
のように--targetで指定すればどこでもできる。
更新。
ChangeLog:
* depend :remove win32ole.c * win32ole.c (fole_s_const_load): accept type library as first argument. * testWIN32OLE.rb (test_s_const_load): ditto. * win32ole.c (ole_method_help): get parameter name.
最初の$もquoteしないとやっぱまずいよね。
% bash -c "a=\$'foo bar';echo \$a" foo bar % zsh -c "a=\$'foo bar';echo \$a" foo bar % ksh -c "a=\$'foo bar';echo \$a" foo bar % ash -c "a=\$'foo bar';echo \$a" $foo bar % pdksh -c "a=\$'foo bar';echo \$a" $foo bar
結果は同じではあるが。
install.rbを書き換えるのを忘れていた。すまん。なひさん。
rsyncは忘れないんだけど、xdeltaを忘れてしまうことがあるようだ。 たまに壊れるのはそういうことなんだな。 これは例によって手動だから忘れるわけで、 rsyncしてついでにxdeltaもするスクリプトを書かないとだめだな。
ltrace ls -lしてみるとdcgettextした結果に変化がない。 fileutils-4.1のpo/ja.poを見ると
#: src/ls.c:1374 msgid "%a %b %d %H:%M:%S %Y" msgstr "" #: src/ls.c:1377 msgid "%b %e %Y" msgstr "" #: src/ls.c:1378 msgid "%b %e %H:%M" msgstr ""
となってて、これじゃ変化ないよね。 でも月だけは「1月」となるから、strftime内部でも変換しているようだ。 早速実験だ。
% cat test.c #include <stdio.h> #include <locale.h> #include <time.h> main() { char buf[1024]; time_t t = time(0); struct tm *tm = localtime(&t); setlocale(LC_ALL, ""); strftime(buf, sizeof buf, "%a", tm); printf("%s\n", buf); } % gcc test.c % ./a.out Tue % LC_ALL=ja_JP.eucJP ./a.out 火
というかman strftimeすると「現在のロケールで」っていっぱい書いてあるじゃん。
<zt diary> 経由でysjjさんの書かれた bashスクリプトでメッセージカタログ を見て、ふむふむとfileutilsのpo/ja.poを書き換えてみた。 そもそもなぜ空なんだろう?
#: src/ls.c:1374 msgid "%a %b %d %H:%M:%S %Y" msgstr "%Y年%m月%e日 %H時%M分%S秒" #: src/ls.c:1377 msgid "%b %e %Y" msgstr " %Y年 %m月%e日" #: src/ls.c:1378 msgid "%b %e %H:%M" msgstr "%m月%e日 %H時%M分"
てな感じ。だが全然変わらない。 ソースを見ると肝心のところがLC_TIMEになっている。 これってLC_MESSAGESの間違いじゃないかな?
% LC_ALL=ja_JP.eucJP ./ls -l ls -rwxr-xr-x 1 watanabe ruby 56388 01月29日 02時36分 ls
ほら。ちゃんと出たじゃん。 これですべて謎が解けたんだろうか?
po/Makefileを見てたら
timedir=$$destdir/$$lang/LC_TIME; \ rm -fr $$timedir; \ ln -s LC_MESSAGES $$timedir \ || (mkdir $$timedir && ln $$dir/* $$timedir); \ echo "installing $$timedir as an alias for $$dir"; \
とある。ひょっとして最初からあるファイル
/usr/share/locale/ja_JP.eucJP/LC_TIME
がいけない気がする。aliasって書いてあるしなあ。 ls.cをもう一度よく見ると他は_()マクロを使っているのに、 ここだけdcgettextでLC_TIMEを指定してる。 ということは間違いじゃなくて、やはり意図的なんだ。うーむ。
そんな気がして
% cd /usr/share/locale/ja_JP.eucJP % sudo mv LC_TIME{,.orig} % sudo ln -s LC_MESSAGES LC_TIME
するとls.cにパッチをあてなくてもちゃんと表示される。 そういうことらしい。
ふだんはLC_MESSAGES=C LC_TIME=C LC_COLLATE=Cという設定をしてるので、 一々
% env -u LC_MESSAGES -u LC_TIME -u LC_COLLATE ls -l
とかしてたんだけど、
% LC_ALL=ja_JP.eucJP ls -l
でいいんだと気づく(strftimeの実験時に)。
% LC_ALL=ja_JP.eucJP locale LANG=ja_JP.eucJP LC_CTYPE="ja_JP.eucJP" LC_NUMERIC="ja_JP.eucJP" LC_TIME="ja_JP.eucJP" LC_COLLATE="ja_JP.eucJP" LC_MONETARY="ja_JP.eucJP" LC_MESSAGES="ja_JP.eucJP" LC_PAPER="ja_JP.eucJP" LC_NAME="ja_JP.eucJP" LC_ADDRESS="ja_JP.eucJP" LC_TELEPHONE="ja_JP.eucJP" LC_MEASUREMENT="ja_JP.eucJP" LC_IDENTIFICATION="ja_JP.eucJP" LC_ALL=ja_JP.eucJP
ええ。ですからすでに /bin/shをashに してしまったのです。 だからこそ、KornShellのmakeではまったわけなんですが、 そう言った意味ではあれは一体なんのチェックなんだか謎になってしまうか?
% mkdir tmp; cd tmp % touch a % bash -c 'function ls { echo ls } ls -l' ls % sh -c 'function ls { echo ls } ls -l' function: not found ls total 0 -rw-r--r-- 1 watanabe ruby 0 Jan 29 02:48 a % sh -c 'ls() { echo ls } ls -l' ls
今日も盛大にメール配送が遅れてる。間違いなくW32/Myparty@MMの所為だな。 uuencodeという手口が温故知新だが、だから猿のようにクリックするなよ、頼むから。
なんとなくamazon.comのほうが安い気もするが、amazon.co.jpで注文。 一ヶ月ぐらいかかる?
なぜ足したかというと、mingwですらなくても文句はなかったから。 つまりcygwinとmingw版は酒井さんとわたししかmakeしたことがないんだと思う。
でもholonのX on Windowsがあるからこれから増えるかもしれないなあ。
--without-extが新設されたので、djgppは
% i386-msdosdjgpp-ruby ../setup.rb config \ --without-ext \ --ruby-path=/usr/local/bin/ruby
てな感じでok。
うそうそ。引数が逆。
ifneq (,$(findstring cygwin,$(TARGET))) TARGET=i386-cygwin endif ifneq (,$(findstring mingw,$(TARGET))) TARGET=i386-mingw32 endif ifneq (,$(findstring djgpp,$(TARGET))) TARGET=i386-msdosdjgpp endif
更新。
入れてみた。
RbProf も同梱されてる。Rubyに付属のprofile.rbより5倍から10倍速いらしい。 実際に実行するとmarshal.dumpした結果が残る。たとえば
% ruby -rrbprof -rjcode -e '"abcde".tr("a-z","A-Z")'
なら-e.profileてな具合に。 でも実際のコードは"w"と"r"でopenしてるからDOSやWindowsではまずそうだな。
File.open(profile_filename(programName), "w") do |f| f.write Marshal.dump(profiler) end
これは普通
File.open(profile_filename(programName), "wb") do |f| f.write Marshal.dump(profiler) end
とするところだが、Marshal::{dump,load}はportが指定されたら自動的にbinmodeするので
File.open(profile_filename(programName), "w") do |f| Marshal.dump(profiler, f) end
でもいい。とりあえず直しとこう。
2回目以降は前回の結果と比較して、その差を表示してくれる。 最適化に燃えるときなんかにいいかも。
Compared to profile taken Wed Jan 30 23:11:21 JST 2002 ****************************************************** New Old Diff Total elapsed time 0.3 0.33 -9.09% TOPLEVEL 0.28 0.31 -9.68% String#tr! 0.02 0.02 -0.00% String#expand_ch_hash 0.0 0.0 String#_expand_ch 0.0 0.0 String#_regex_quote 0.0 0.0 String#tr 0.0 0.0
pure rubyのtar。なぜかライブラリではなくコマンドとして実装されてる。 最後はif __FILE__ == $0のイディオムを使って欲しいなあ。 これでsetup.exeを使わないインストーラを作るのも悪くないかも。 でもsetup.exeを使っている人は当然Cygwinをインストールしてるはずで、 systemでtarを呼べばいいか。 あ、Rubyで書くとruby.exeとcygwin-ruby16.dllあたりが更新できない気がする。
READMEを見てパッケージングは見送り。
中はCR+LFだなあ。いやだな。
stray '\' in program
になるんだよね。 というか、たしかgcc 2.95.3からはCR+LFも受けつけるようになったはずなんだけどなあ。 3.0からだっけ?
Requirements? ------------- ANSI C compiler, Ruby and cygwin.
というのはなんでだろう?MinGWでも問題なくperfctr.soは作れるんだけど。 たぶんVC++でもいけるんじゃないかな。肝は
QueryPerformanceFrequency QueryPerformanceCounter
のようだ。
これを使ってhigh-resolutionになるのなら、 win32/win32.cのgettimeofdayもそうすればいい気もする。 でもよく見たらこれって絶対じゃなくて相対なのか。うーむ。