〜2002年9月中旬〜
なんかよくわからないけど、結構人気があるようだ。 コンパイルする環境があるならmakeも当然あるはずで、 実行時間を気にしなければmkmf.rbでMakefileを作ってmakeすればいい気もする。
RUBY_PLATFORMで判断してるものは、できるだけrbconfig.rbへ追い出せば、少しはすっきりするかな。
create_makefileは連休中にでもゆっくり考えよう。
50000を越えた。
なぜか/usr/local/libがlibrary pathから外れてる。これはちょっといやだな。
実は過去2回程この件でメール書こうと思ったんだけど、 何か意味があるような気がしてやめてたりする。 で、今回も
$INSTALLFILES ||= nil
と最初に書いてwarningくらって今日こそはメール書くかと思ったが、 そのまま会議に突入してしまったのであった。
CygwinとMinGWはi386に正規化してます。
case "$target_os" in cygwin*|mingw*) AC_CHECK_TOOL(NM, nm) AC_CHECK_TOOL(WINDRES, windres) AC_CHECK_TOOL(DLLWRAP, dllwrap) target_cpu=`echo $target_cpu | sed s/i.86/i386/` : ${enable_shared=yes} ;; esac
program_prefixも対処したので、今は--program-prefix=''しなくてもruby.exeになります。
mswin32もi386になるかのかとwin32/README.win32を見ると、 configure時に指定しなきゃいけない? それじゃ、i386-msvcrt化計画もちょっとまずいような。
[ruby-dev:18288]で宣言したように考えることにする。 AC_PROG_CPPの後でこんな感じでcheckかな。
echo 'foo(){}' > conftest.c if ${CPP} -o conftest.i conftest.c >/dev/null 2>&1; then CPPOUTFILE='-o conftest.i' else CPPOUTFILE='> conftest.i' fi AC_SUBST(CPPOUTFILE)
ビデオに録っておいたものを今日見た。くー。続きは「きょうの出来事」でってどーゆーことよ?
久し振りにbk pullしてみるとarch/um/ができてる。 User-Mode Linuxが取り込まれたらしい。でもいきなりinit/main.cがエラーになってしまう。 あ、oldconfig時にARCH=umを忘れてた。同じだな。うーむ。
できるだけrbconfig.rbへ追い出そうと思う。一個ずつ見ていこう。
これって特に限定する必要はない気がする。外そう。
CFLAGS="$CFLAGS -fansi-only -cc1-stack=262144 -cpp-stack=2694144"
の-cc1-stack, -cc2-stackを削除してる。これはこのままかな。
fat-binary関係する-archを削除している。これもこのまま残そう。
configure.in, */Makefile.subで対応。
mswin32は/libpathを使い、bccwin32は-Lを使う。 あれ?一部bccwin32では-Lを使ってるなあ。 それはそれとしてLIBPATHFLAGを新設しよう。
bccwin32のときの一時ファイル。bcc32は余計なファイルを作りすぎる。 これはしょうがないから残そう。。
これはどうすべきかな? $libsは-lfooのままで、Makefileを書き出すときに変換するのはどうかな。 mswin32のほうも-libpathを使えば、
gsub(/-l(.+)(?:\s)/, '\1.lib') if /^cl/ =~ Config::CONFIG['CC'] gsub(/-L/, '-libpath:') if /^cl/ =~ Config::CONFIG['CC']
という感じでうまくいかないかなあ。
-lmが独立していない処理系では無条件でtrueを返したい。 -lmだけとも限らないのでrbconfig.rbにそのライブラリリストをHashで用意する?
さらに例の#include "ruby.h"を入れよう。 とすれば前半部分は共通になるはず。 srcの最後に\nがない場合は追加する処理も入れよう。
あれ?ここはwin32用の処理に分かれてないね。
結局のところhave_library, find_library, have_funcの共通項をくくり出さないといかんですな。
これはとりあえず後。
makeぐらいはrbconfig.rbで用意すべきか?
autoconfのように失敗したソースもlogに残そう。いや、常に残そう。 ついでに何のcheckなのかも。
OUTFLAGとCPPOUTFILEとわかりやすいログを中心に変更。
http://www.ntv.co.jp/によると10月6日(日)24:25から再放送するらしい。 「熱いご要望」とか書いてあるが、苦情が殺到したに違いない。
定数へ戻すことにしよう。
$LIBPATH, ENV['LIB'], ORIG_LIBPATH, $LDFLAGSといっぱいからんでるねえ。 $LIBPATHはディレクトリを要素にもつ配列なので、 実際に使うときは-Lをprefixさせる必要がある。
$LDFLAGS << $LIBPATH.join(" -L")
じゃ最初の要素には-Lがつかないのでだめ。というわけで
$LIBPATH.each {|d| $LDFLAGS << " -L" + d}
となっているけど、
$LDFLAGS << ([""] + $LIBPATH).join(" -L")
というのはどうだろう?なら最初から$LIBPATHに入れとけって?ごもっとも。 というわけで
$LIBPATH = [""]
と初期化しとくといいかも。 find_libraryがあるからだめだ。 やっぱ[""] +で我慢するか。
-libpathを使えばENV['LIB'], ORIG_LIBPATHをいじる必要はない。 VC++がないだけにcheckできないとこが齒痒い。 clとlinkとlib command wrapperを作るべきか? どこかにありそうだな。
順番に見て行く。
src = "/* begin */\n#{src}/* end */\n"
これはわかりやすいログ対応なので、ログだけにしよう。
src += "\n" unless /\n\z/ =~ src
に変更。
cfile = open("conftest.c", "w") cfile.print src cfile.close
try_compile, try_cpp, egrep_cppに共通なので、 create_tmpsrcというmethodにして外へ出す。 ついでにCONFTEST_C = "conftest.c"とする。
def create_tmpsrc(src) open(CONFTEST_C, "w") do |cfile| cfile.print src end end
次がENV['LIB']と$LDFLAGSをいじってるとこだけど、
ldflags = $LDFLAGS if /mswin32|bccwin32/ =~ RUBY_PLATFORM and !$LIBPATH.empty? ENV['LIB'] = ($LIBPATH + [ORIG_LIBPATH]).compact.join(';') else $LDFLAGS = ldflags.dup $LIBPATH.each {|d| $LDFLAGS << " -L" + d} end
ENV['LIB']はいじる必要ないので削除。" -L"じゃなくてLIBPATHFLAGを使う。
ldflags = $LDFLAGS $LDFLAGS = ldflags.dup $LIBPATH.each {|d| $LDFLAGS << LIBPATHFLAG + d}
なんかldflagsと$LDFLAGSの関係が変だね。そもそも$LDFLAGSは次の
xsystem(format($LINK, $INCFLAGS, $CPPFLAGS, $CFLAGS, $LDFLAGS, opt, $LOCAL_LIBS))
へ渡すためにあるんだけど、ここで引数になってるので$LDFLAGSである必要もない。 ensureで元に戻してるくらいだし。 $LIBPATHの内容を反映させればいいだけなので
ldflags = $LDFLAGS + ([""] + $LIBPATH).join(" " + LIBPATHFLAG) xsystem(format(LINK, $INCFLAGS, $CPPFLAGS, $CFLAGS, ldflags, opt, $LOCAL_LIBS))
で十分だろう。最後にログにcheckしたソースを残す処理だけど、
Logging::message <<"EOM" checked program was: #{src} EOM
は外に出してmethodとする。
def log_src(src) Logging::message <<"EOM" checked program was: /* begin */ #{src}/* end */ EOM end
最終的にtry_link0はこうなった。
def try_link0(src, opt="") src += "\n" unless /\n\z/ =~ src create_tmpsrc(src) ldflags = $LDFLAGS + ([""] + $LIBPATH).join(" " + LIBPATHFLAG) xsystem(format(LINK, $INCFLAGS, $CPPFLAGS, $CFLAGS, ldflags, opt, $LOCAL_LIBS)) ensure log_src(src) end
基本的に同じ変更。
begin src += "\n" unless /\n\z/ =~ src create_tmpsrc(src) ... ensure log_src(src) end
の構造は同じなので、try_doとしてmethodへ。
def try_do(src, command) src += "\n" unless /\n\z/ =~ src create_tmpsrc(src) xsystem(command) ensure log_src(src) end
xsystemはsystemの戻り値と同じでtrueとfalseを返す。よって
if xsystem("./conftest") true else false end
は冗長。
xsystem("./conftest")
だけでいい。
LINK定数はformatへ渡すために%sがあるが、これがわかりにくい要因になってるようだ。
LINK="#{CONFIG['CC']} #{OUTFLAG}conftest %s -I#{$hdrdir} %s \ #{CFLAGS} %s #{CONFIG['LDFLAGS']} %s #{CONFTEST_C} %s %s \ #{CONFIG['LIBS']}"
LINKが使われているのはtry_link0の中で
xsystem(format(LINK, $INCFLAGS, $CPPFLAGS, $CFLAGS, ldflags, opt, $LOCAL_LIBS))
という感じ。この引数とLINKの関係が離れているのもわかりにくい。 %sの数と引数の数が合ってるかどうかも不安だし(引数のほうが多い場合はエラーにならない)。 かといってLINK =をtry_link0の前に置いたところであまり改善された気がしない。 このグローバル変数をLINKの中にしまいこむにはどうすればいいのか? methodにして
def link_format "#{CONFIG['CC']} #{OUTFLAG}conftest #$INCFLAGS -I#{$hdrdir} " + "#$CPPFLAGS #{CFLAGS} $CFLAGS #{CONFIG['LDFLAGS']} %s " + "#{CONFTEST_C} %s #$LOCAL_LIBS #{CONFIG['LIBS']}" end
という手はあるね。これで
xsystem(format(link_format, ldflags, opt))
と書ける。でも、それならformatもなくして
def link_command(ldflags, opt="") "#{CONFIG['CC']} #{OUTFLAG}conftest #$INCFLAGS -I#{$hdrdir} " + "#$CPPFLAGS #{CFLAGS} $CFLAGS #{CONFIG['LDFLAGS']} #{ldflags} " + "#{CONFTEST_C} #{opt} #$LOCAL_LIBS #{CONFIG['LIBS']}" end xsystem(link_command(ldflags, opt))
のほうがいいか。あ、$LDFLAGSも中に入れちゃえばいいんだ。
def link_command(ldflags, opt="") "#{CONFIG['CC']} #{OUTFLAG}conftest #$INCFLAGS -I#{$hdrdir} " + "#$CPPFLAGS #{CFLAGS} #$CFLAGS #{CONFIG['LDFLAGS']} #$LDFLAGS " + "#{ldflags} #{CONFTEST_C} #{opt} #$LOCAL_LIBS #{CONFIG['LIBS']}" end def try_link0(src, opt="") try_do(src, link_command(([""] + $LIBPATH).join(" " + LIBPATHFLAG), opt)) end
となる。このjoinもよく出てくるので外に出す。
def libpathflag ([""] + $LIBPATH).join(" " + LIBPATHFLAG) end def try_link0(src, opt="") try_do(src, link_command(libpathflag, opt)) end
Config::expandで展開されるのでCONFIG['CC']は$(CC)にしてみよう。
結局PLATFORM依存の処理は残るので
$mswin = /mswin/ =~ RUBY_PLATFORM $bccwin = /bccwin/ =~ RUBY_PLATFORM $mingw = /mingw/ =~ RUBY_PLATFORM $cygwin = /cygwin/ =~ RUBY_PLATFORM $human = /human/ =~ RUBY_PLATFORM
を用意した。
bccwin32では-Lc:/foo/barじゃなくて-L"c:/foo/bar"にしないと、 /barというオプションとみなされるようだ。
def libpathflag q = $bccwin ? '"' : '' $LIBPATH.map do |x| " #{LIBPATHFLAG}#{q}#{x}#{q}" end.join end
空白を含むディレクトリを考えると$bccwinに限った話でもないか。
def libpathflag $LIBPATH.map do |x| %Q[ #{LIBPATHFLAG}"#{x}"] end.join end
というわけで、空白を含む作業ディレクトリでmakeしてみよう。 あ、全然だめだ。これは後だね。
commitはまだだな。もうちょっと別の環境で試そう。
基本的には-Lの代わりに-link -libpath:にするだけと思っているので、 対応も何もないというか、あ、/を\へ変換ぐらいはするかもしれない。 makeの機能だとhave_libraryの時に対応できないので、 rubyで変換するしかないかなあ。 というのもあって、昨日の-L"c:/foo/bar"の話になるのであった。 変換しないで済むなら済ませたいというか。
bk pullがやけに長い。XFSが入ったのか。
うーむ。それはちょっと予想外の展開です。 gccの-Wlと同じで、-Lは-link -libpath:で置き換え可能だと思っていたのに。 commitしなくて正解だった。
#{CONFIG['LDFLAGS']}, #$LDFLAGS, ldflagsを後ろに移動して
def link_command(ldflags, opt="") ldflags = "-link " + ldflags if $mswin "$(CC) #{OUTFLAG}conftest #$INCFLAGS -I#{$hdrdir} " + "#$CPPFLAGS $(CFLAGS) #$CFLAGS #{CONFTEST_C} #{opt} " + "#$LOCAL_LIBS $(LIBS) #{ldflags} $(LDFLAGS) #$LDFLAGS" end
としようかな(以前とはまたちょっと形が違ってますが)。
ruby-bugsもサイズ制限して欲しい。
- Added some compatibility code for windows.
が気になってinline.rbを見てみた。単にmkmf.rbから抜き出しただけだ。 なぜ-linkなんだと思ったら、既に$local_flagsで-linkしてたのであった。 これも考慮しないといけないなあ。
まずはENV['LIB']のままrefactoringを進めるべきか。
mkmf.rbでlib/*.rbだけの場合に対応しとくとそれなりに便利かも。
cygwinでautoconfするとなぜかconfigureがDOS line endingsになってしまう。 もちろんbinary mountしてるのにもかかわらずだ。 追ってみると最終的にはautom4teがconfigureを作っているが、 これはperl scriptになっている。この中で
$out->open($output, O_CREAT | O_WRONLY | O_TRUNC, oct ($mode));
と実行してる。 ということはCygwinのperlはmount modeに関係なくtext modeで書くのか? 実にいやな仕様だな。
% ruby -e 'print "\n"' |od -c 0000000 \n 0000001 % perl -e 'print "\n"' |od -c 0000000 \r \n 0000002
メンテナのGerrit P. Haase氏の趣味だろうか? と思ったら5.6.1はちゃんとmount modeに従っている。
% perl5.6.1 -e 'print "\n"' |od -c 0000000 \n 0000001
5.8.0での変更のようだ。Cygwin MLを調べる必要があるな。