〜2002年12月下旬〜
[ruby-dev:19149]とconflictしそうな気もするので、 この件はとりあえず保留。 あ、でも1.6を望んでるのか。
Cygwinもgcc 3.2になってspecsが変更されたから、 そろそろちゃんと対応してあげよう。
更新。
たとえばversion.hを
#define RUBY_VERSION "1.7.3" #define RUBY_RELEASE_DATE "2002-12-20" #define RUBY_VERSION_CODE 173 #define RUBY_RELEASE_CODE 20021220 #if 0 MAJOR=1 MINOR=7 TEENY=3 #endif
としてしまえば、configure.inも単に
. $srcdir/version.h
で済むし、win32/Makefile.subも!includeを使えるんじゃないかと思ったりする。 でも1と7と3をversion.hの中に更に増やしてどうする。ボツだな。
それはそれとして、同じものを2回書くのはやはり避けたい。 ANSI Cが必須となった今なら
#define RUBY_MAJOR 1 #define RUBY_MINOR 7 #define RUBY_TEENY 3 #define RUBY_YEAR 2002 #define RUBY_MONTH 12 #define RUBY_DAY 20 #define __S(x) #x #define _S(x) __S(x) #define __C(x,y,z) x ## y ## z #define _C(x,y,z) __C(x,y,z) #define RUBY_VERSION _S(RUBY_MAJOR) "." _S(RUBY_MINOR) "." _S(RUBY_TEENY) #define RUBY_RELEASE_DATE _S(RUBY_YEAR) "-" _S(RUBY_MONTH) "-" _S(RUBY_DAY) #define RUBY_VERSION_CODE _C(RUBY_MAJOR, RUBY_MINOR, RUBY_TEENY) #define RUBY_RELEASE_CODE _C(RUBY_YEAR, RUBY_MONTH, RUBY_DAY)
という手もあるか?これで最後の4つはそれぞれ
"1" "." "7" "." "3" "2002" "-" "12" "-" "20" 173 20021220
と展開される。
#define _S(x) __S(x) #define _C(x,y,z) __C(x,y,z)
の部分は意味がないように思えるが、 K&R2にも書いてあるように間接的に参照する必要がある。
ぎりぎり128KB制限に収まっているようだ。 htmlメールを受け付けないようにすれば、 spamも減るし、碌でもないメールも減るし、 一石二鳥どころか三鳥にもなる気が。
パッケージングしたら同じ名前で更新されていた。 一部ドキュメントが追加されたようだ。
foo.soのような共有ライブラリを必要としない、 pure rubyなライブラリしかないxmlscanのようなライブラリをサポートするために、 mkmf.rbを改造してみた。1.6, 1.7共にcommit済み。 構造としてはスクリプトがlib/配下に置かれていればいい。
たとえばxmlscanなら
% ruby -rmkmf -e 'create_makefile("xmlscan")' % sudo make site-install
だけでいける。
djgpp/mkver.sedがversion.hに依存しているので対応する。 元々RUBY_VERSIONの行から
s,@MAJOR@,1,;s,@MINOR@,7,;s,@TEENY@,3,
というsedスクリプトを生成するsedスクリプトだが、単に
s/^#define RUBY_\(MAJOR\|MINOR\|TEENY\) \([0-9][0-9]*\)$/s,@\1@,\2,/p
を追加するだけで、新旧両方のversion.hに対応できることに気づく。 新version.hを食わせると
s,@MAJOR@,1, s,@MINOR@,7, s,@TEENY@,3,
となる。最初はgcc -Eを使おうと思ったけど、 このほうが変更が少なくてよさそうだ。
#include "version.h" MAJOR=RUBY_MAJOR MINOR=RUBY_MINOR TEENY=RUBY_TEENY
をAC_TRY_CPPした結果をsourceするという作戦でいこうと思ったが、 新旧対応しといたほうが何かと便利か?ま、いいや。シンプルに行こう。
更新。
油断してたらリリースされてしまった。明日だと思ってたんだけどなあ。
結局
RUBY_VERSION_MAJOR RUBY_VERSION_MINOR RUBY_VERSION_TEENY RUBY_RELEASE_YEAR RUBY_RELEASE_MONTH RUBY_RELEASE_DAY
という名前になった。 最終的には3つに増えたわけだけど、 これは手で修正するのではなくスクリプトを介して変更するということで。
そういえば ext/dbm/extconf.rbの""で囲む件はすっかり忘れてた。まずいなあ。 MLをもう一度見てみると [ruby-dev:19088]や [ruby-list:36821]が気になる。Cygwinに関しては多分その人の環境の問題だと思うから、 とりあえずいいとして、Solaris 8の件はやっぱ
try_link(<<EOF, $libs) try_run(<<EOF, $libs)
とすべきか?
RUBY_RELEASE_で統一されたので
formats = { 'RELEASE_DATE' => [/".+"/, '"%Y-%m-%d"'], 'RELEASE_CODE' => [/\d+/, '%Y%m%d'], 'RELEASE_YEAR' => [/\d+/, '%Y'], 'RELEASE_MONTH' => [/\d+/, '%m'], 'RELEASE_DAY' => [/\d+/, '%d'] }
でいいわけだが、そうすると今度は共通項のRELEASE_を外に出して
formats = { 'DATE' => [/".+"/, '"%Y-%m-%d"'], 'CODE' => [/\d+/, '%Y%m%d'], 'YEAR' => [/\d+/, '%Y'], 'MONTH' => [/\d+/, '%m'], 'DAY' => [/\d+/, '%d'] }
として
if /RUBY_RELEASE_(#{formats.keys.join('|')})/o =~ line
としたくなるよね。やっぱ。 ここに置いとこう。
% ruby syncver.rb #define RUBY_VERSION "1.8.0" #define RUBY_RELEASE_DATE "2002-12-25" #define RUBY_VERSION_CODE 180 #define RUBY_RELEASE_CODE 20021225 #define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MINOR 8 #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2002 #define RUBY_RELEASE_MONTH 12 #define RUBY_RELEASE_DAY 25
で確認して
% ruby -i~ syncver.rb
てな感じで書き換える。
最近のCygwinのmakeは最初から--unix相当になっているらしく、 MAKE_MODEでunixと設定する必要もないようだ。 それはそれとして、MFLAGSとMAKEFLAGSは
% cat -T Makefile all: ^I@echo $(MFLAGS) ^I@echo $(MAKEFLAGS) % make - --unix --unix
となるので、ext/extmk.rbには
./miniruby.exe ../ruby/instruby.rb --make="make" --make-flags="- --unix --unix"
が渡される。 - --unixってのはかなり謎だが、というか最初の-はバグじゃない?
それとCygwin上ではMAKEFLAGSは-がそのまま残るが、 Linuxだと-は削除される。
Linux: % make -n echo -n echo n Cygwin: % make -n echo - --unix -n echo --unix -n
versionはどちらも3.79.1なので、CygwinのGNU makeはかなり手が入っているということか。
% ruby -rmkmf -e 'create_makefile("foo")' % make rubylibdir=$HOME/ruby install
ってことじゃないんだよね、たぶん。
躊躇してると油断になってしまうので、どんどんcommitしていこうと思う。 mingwはinstallできなくなっていた。
なぜかconfigure.inとChangeLogがcommitされなかった。 historyを見ると引数に指定されてるんだけどなあ。 あれ?version.hもだ。しまったなあ。 日付が変わる直前にcommitするとこういう目に会うのか。うーむ。
え?1.6.8って1.6系の最後なの? だとすると例のdbmの件もcommitしても無駄なんだろうか? 確かに1.8が順調に出れば事実上最後になっても不思議はないけど。
debugしてたらなかださんが直してくれた。まいどです。
ext/extmk.rbの動きを追っていたらどうにも腑に落ちない挙動に出喰わす。 勝手にquoteしてる感じだ。簡単なMakefileを書いて検証してみる。
% cat Makefile all: ruby -e 'p ARGV' foo="a b" "a" ruby -e 'p ARGV' foo "a b" "a" % nmake -nologo ruby -e 'p ARGV' foo="a b" "a" ["foo=\"a b\"", "a"] ruby -e 'p ARGV' foo "a b" "a" ["foo", "a b", "a"]
と=の有無で挙動が変わる。borland makeでも同様。
% make ruby -e 'p ARGV' foo="a b" "a" ["foo=a b", "a"] ruby -e 'p ARGV' foo "a b" "a" ["foo", "a b", "a"]
となって欲しいんだけどねえ。{win32,bcc32}/Makefile.subでは
--make-flags="-$(MFLAGS)$(MAKEFLAGS) DESTDIR=$(DESTDIR)"
のようにext/extmk.rbの引数として渡しているので、""が残ってしまう。 つまり、ext/extmk.rbでの
$mflags = Shellwords.shellwords($OPT['make-flags'] || "")
が機能しないので、
% nmake DESTDIR=c:/ruby install
とした場合、DESTDIRの値が正しく伝わらない。というわけで
--make-flags "-$(MFLAGS)$(MAKEFLAGS)"
と=は削除したほうがいいね。
あ、instruby.rbも変更しなきゃだめだな。こっちもgetoptsを使おう。
dryrunはだめみたい。
bccwin32: % make -n install MAKE Version 5.2 Copyright (c) 1987, 2000 Borland .\miniruby.exe C:/cygwin/home/watanabe/ruby/ruby/instruby.rb --make "make" --make-flags "-l -n -o " /usr .\miniruby.exe C:/cygwin/home/watanabe/ruby/ruby/ext/extmk.rb --make "make" --make-flags "-l -n -o DESTDIR=/usr" install mswin32: % PATH=/c/vc/bin:$PATH nmake -n install Microsoft (R) Program Maintenance Utility Version 7.10.2197.8 Copyright (C) Microsoft Corporation. All rights reserved. .\miniruby.exe ../ruby/instruby.rb -N /usr .\miniruby.exe ../ruby/ext/extmk.rb --make "nmake" --make-flags "-N DESTDIR=/usr" install
mingwは、あれ?エラーになるなあ。これは 例のsystem問題がからんでるねえ。
$mflags.unshift("INSTALL_PROG=install -m 0755", "INSTALL_DATA=install -m 0644") if $dryrun
で
system($make, *$mflags)
という感じで実行されるので。今のmingw32版rubyではquoteする必要がある。 あ、 [ruby-dev:19130]はそういう意味か。でもそうすると正しく動くsystemを持つ処理系では
"install -m 0755" win32ole.so /usr/local/lib/ruby/1.8/i386-cygwin
と残るんだよねえ。うささんがやる気なしモードに入ってしまったのが痛い。うーむ。 とりあえず致命的じゃないし放っておくか。
まただ。instruby.rb, ChangeLog, version.hがなぜかcommitされなかった。うーむ。
そういえばなぜ Ruby Binariesを登録してなかったんだろう? お願いされるまで全く思い付かなかったようだ。
50000が9/12だから3ヶ月で10000か。 [ruby-talk:60013]
3ヶ月振りにCMを見た。
nmakeした後にtouch win32/Makefile.subしてnmakeすると、 インポートライブラリext/gdbm/gdbm.libが存在するため
fatal error LNK1149: 出力ファイル名と入力ファイル名 \ 'C:\cygwin\home\watanabe\ruby\mswin\ext\gdbm\gdbm.lib' が同じです。
となってしまう。DLLIBのコマンドに
mfile.print "@-$(RM) $(TARGET).lib\n\t" if $mswin
を足しとこう。
いちいちdefined?しなきゃいけないのは使い難いから、 普通のときはnilにしたいなあ。 今はfake.rbで設定しているから、mkconfig.rbをいじってrbconfig.rbの最後に
CROSS_COMPILING = nil unless defined? CROSS_COMPILING
を入れるようにしよう。
Config::CONFIGに入れちゃうと、 crossで作ったbinaryをnativeでmkmf.rbする時に困ったことになりそう。
結局ext/extmk.rbで最後のsystemのquote処理と同じようなことをしないとい けないことになったと思ったら、 patchが出てきてしまった。
それはそれとして、ext/extmk.rb側で対応するとしたら
host = (defined?(CROSS_COMPILING) ? CROSS_COMPILING : RUBY_PLATFORM) /mswin|bccwin|mingw|djgpp|human|os2|macos/ =~ host
の部分をまとめる必要がありそうだ。CROSS_COMPILINGの話はここにつながる。 nilになってれば
/mswin|bccwin|mingw|djgpp|human|os2|macos/ =~ (CROSS_COMPILING || RUBY_PLATFORM)
ですむ。 それはそれとしてdjgppは本当にこうする必要があるのだろうか? というより、system複数引数問題はdjgppにもあるじゃん。 joinしてsystemしてるだけだし。djgppもhuman68kを参考にspawnを使うようにしよう。
いつのまにか0.8aになってた。気づくの遅すぎ。
更新。
そうか。なるほど。ruby以外のプログラムで検証すべきだった。
更新。
そもそもなぜGNU makeだとmake -nでminirubyが起動されるんだろう? どう考えても挙動としてはnmake系のほうが正しい。 info makeしてGNU makeの仕様を眺めてみるとFeature of GNU `make'に以下の記述が見つかった。
* Execution of recursive commands to run `make' via the variable `MAKE' even if `-n', `-q' or `-t' is specified. *Note Recursive Use of `make': Recursion.
Noteを読むとMAKE変数について書いてあった。
How the `MAKE' Variable Works ----------------------------- Recursive `make' commands should always use the variable `MAKE', not the explicit command name `make', as shown here: subsystem: cd subdir && $(MAKE) The value of this variable is the file name with which `make' was invoked. If this file name was `/bin/make', then the command executed is `cd subdir && /bin/make'. If you use a special version of `make' to run the top-level makefile, the same special version will be executed for recursive invocations. As a special feature, using the variable `MAKE' in the commands of a rule alters the effects of the `-t' (`--touch'), `-n' (`--just-print'), or `-q' (`--question') option. Using the `MAKE' variable has the same effect as using a `+' character at the beginning of the command line. *Note Instead of Executing the Commands: Instead of Execution.
なるほど。MAKEという変数を参照することに意味があるわけだ。 all:もinstall:もコマンドには--make "$(MAKE)"という形で使われている。 instruby.rbには--makeは必要ないが、 このMAKE変数を使わなきゃいけないという点で外しちゃいけないわけか。 実は消しちゃおうと思っていたところだったのだ。あぶない。あぶない。
% cat Makefile all: @echo hello @echo $(MAKE) % make hello make % make -n echo hello echo make make
GNU makeの機能だから当然他のmakeでは使えない。 だったら、別のターゲットを用意すればいい? dryrunとかdryrun-installとか。apel系のwhat-whereでもいいかな。 どうせ-nしたくなるのはmake installの時だけだから。
Perlもそのあたりは同じだから調べてみると、 5.6以降はno-installというターゲットが用意されてるようだ。 やはり人間考えることは同じらしい。
no-install: $(MAKE) install.perl install.man STRIPFLAGS=$(STRIPFLAGS) INSTALLFLAGS=-n
djgppだけでもなんとかするためにprocess.cをいじる。 defined(_WIN32)を2個所ほど追加すればいいようにしとけば、 うささんが戻ってきたときに簡単に対応できるかな。
ためしにhuman68kのコードを活かしてmsvcrt.dllのspawnvを使ってみたが、 やはり空白があってもquoteしてくれなかった。
12/29に更新してたのだった。
NEWSを見ても特に大きな変更はないようだ。