〜2001年1月上旬〜
% cd /pub/cygwin % tar xfvz gcc-2.95.2-6-src.tar.gz % mkdir build % cd build % lndir ../src # /pub/cygwin/src に cvs co してるので % for i in gcc libstdc++ libio for> do for> mkdir $i for> cd $i for> lndir ../../gcc-2.95.2-6/$i for> cd .. for> done % mkdir obj # これ大事 % cd obj # この階層じゃないと make に失敗する. cygwin って変. % CFLAGS=-Os CXXFLAGS=-Os ../configure --target=i686-pc-cygwin \ --prefix=/usr/local/cygwin --enable-languages=c,c++ \ --enable-targets=i686-pc-cygwin,i386-msdosdjgpp % make % sudo make install
% echo 'main(){}' > foo.c % i686-pc-cygwin-gcc -v foo.cで確認を。PATHを通すのも忘れずに。
% gcc --help | grep -e -b -b <machine> Run gcc for target <machine>, if installedということだ。b mingw packageでももちろんいい。
$prefix/bin $prefix/include $prefix/lib $prefix/$target $prefix/$target/bin $prefix/$target/include $prefix/$target/libここで$prefixはdefaultだと/usr/local *1、$targetはcygwinだとi686-pc-cygwinが入る。
% i686-pc-cygwin-gcc -V 2.95.2-5 -v Reading specs from /usr/local/cygwin/lib/gcc-lib/i686-pc-cygwin/2.95.2-5/specs gcc driver version 2.95.2-6 19991024 (cygwin experimental) executing gcc version 2.95.2-5という感じで呼び出すことができる。 *2
$prefix/lib/gcc-lib/mingw/$version/specs
を使おうとするし、
$prefix/mingw/bin/{as,ld}
等を内部的に実行しようとする。ライブラリも
$prefix/mingw/lib
をまず探す。
% tar xfvz mingw-runtime-0.4-20001204.tar.gz % cd mingw-runtime-0.4-20001204 % mkdir obj % CC=i686-pc-cygwin-gcc CFLAGS=-Os CXXFLAGS=-Os ../configure \ --target=i686-pc-cygwin \ --host=i686-pc-cygwin \ --build=i586-pc-linux-gnu % makeこれできたが、このままmake installしてもあまり意味がないので、 必要なファイルだけを/usr/local/cygwin/mingw以下のコピーする。 なにをコピーするかはCRT0SとLIBSを参考に。
% sudo mkdir -p /usr/local/cygwin/mingw/lib % sudo cp -av crt2.o dllcrt2.o CRT_noglob.o crtmt.o crtst.o \ libmingw*.a libmoldname.a /usr/local/cygwin/mingw/lib/残りはcrtdll.dll用なので要らない。
% echo -n 'hypernikkisystem'|wc 0 1 16ということか。
% ldd cvsup libz.so.1 => /usr/lib/libz.so.1 (0x40019000) libm.so.6 => /lib/libm.so.6 (0x40027000) libc.so.6 => /lib/libc.so.6 (0x40043000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)Installに従い/usr/local/binに置く。
% sudo useradd -m ruby % sudo chown -R watanabe ~ruby % cd ~ruby % mkdir cvs % cat >cvs-ruby.sup *default compress delete use-rel-suffix *default host=cvs.ruby-lang.org *default base=/home/ruby *default release=cvs *default prefix=/home/ruby/cvs cvs-rubyしておいた。準備OK。やってみよう。
% cvsup -gL2 ~ruby/cvs-ruby.sup ... Create www/whats.rd,v Create www/whos.rd,v Create www/wwwgen.rb,v SetAttrs www Shutting down connection to server Finished successfullydoc, ruby, wwwの各コレクションが取ってこれた。 15分ほどで無事終了。 noguiを取ってきたから-gはなくてもいい。
% du -s ~ruby 15667 /home/ruby15MBか。 56Kモデムだけどこれだけ速いということは結構圧縮が効いてる。
% i686-pc-cygwin-gcc -bmingw -v Using builtin specs. gcc version 2.95.2-6 19991024 (cygwin experimental)のように-bmingwをつけてもspecsはbuiltinのものが使われる。 このチェックはちゃんと設定できたかどうかの確認にもなるで重要。
% sudo mkdir -p /usr/local/cygwin/lib/gcc-lib/mingw/2.95.2-6 % sudo touch /usr/local/cygwin/lib/gcc-lib/mingw/2.95.2-6/specs % i686-pc-cygwin-gcc -bmingw -v Reading specs from /usr/local/cygwin/lib/gcc-lib/mingw/2.95.2-6/specs gcc version 2.95.2-6 19991024 (cygwin experimental)このようにspecsを置くとgccは読んでくれる。
% cd /usr/local/cygwin/lib/gcc-lib/mingw/2.95.2-6 % ln -s ../../i686-pc-cygwin/2.95.2-6/* . ln: ./specs: File exists % ls SYSCALLS.c.X cc1plus cpp libgcc.a specs cc1 collect2 include libstdc++.a % cd /usr/local/cygwin/mingw % ln -s ../i686-pc-cygwin/bin .libgcc.a,libstdc++.aはcygwin用なのでこのままでは実はまずい。 mingw用と差し替える必要がある。 これはmingw用gccを作らないと得られないのだが、面倒なので これのlibgcc.aとlibstdc++.aを使ってる。 今なら MingGW Project Infoからgccのbinaryを取ってきたほうがいいだろう。
% cd /usr/local/cygwin % env GZIP=-9 tar cfvz /tmp/bmingw-20010105.tar.gz lib/gcc-lib/mingw mingwこれでやっとできた。 bmingw-20010105.tar.gzはcrossじゃないnativeのcygwinでもそのまま展開すれば使えるようになっている。
% cd /usr % tar xfvz bmingw-20010105.tar.gz % gcc -bmingw -v Reading specs from /usr/lib/gcc-lib/mingw/2.95.2-6/specs gcc version 2.95.2-6 19991024 (cygwin experimental)
% ls /usr/lib/mingw CRT_noglob.o crtmt.o dllcrt2.o libmingw32.a libmsvcrt.a crt1.o crtst.o libcoldname.a libmingwthrd.a libmsvcrt20.a crt2.o dllcrt1.o libcrtdll.a libmoldname.a libmsvcrt40.aということは当然crossのほうにも同じようにあるわけで、うーむ、 一体何をやってたんだ俺は。
% ls /usr/local/cygwin/i686-pc-cygwin/lib/mingw CRT_noglob.o crtmt.o dllcrt2.o libmingw32.a libmsvcrt.a crt1.o crtst.o libcoldname.a libmingwthrd.a libmsvcrt20.a crt2.o dllcrt1.o libcrtdll.a libmoldname.a libmsvcrt40.a
% ls --version ls (GNU fileutils) 3.16気づかなかったけど、こんな違いがあるとは。
*multilib: ../../../../i686-pc-cygwin/lib/mingw ;にしてみた。
cannot open crt1.o: No such file or directoryになることに今頃気づいた。こっちのspecsのmultilibも直さないとだめだ。
*multilib: ../../../../i686-pc-cygwin/lib/mingw mno-cygwin;と
*multilib_matches: mno-cygwin mno-cygwin;を追加。 パッチ
-rw-r--r-- 1 watanabe ruby 173822 Jan 5 20:00 bmingw-20010105.tar.gz -rw-r--r-- 1 watanabe ruby 164825 Jan 6 20:49 bmingw-20010106.tar.gzもっともmsvcrt.dll版rubyを作るだけなら、 1.1.7-1ではすでに材料は揃っているわけで、 bmingw packageは要らない気もする。 crt2.oを指定できればいいんだけど。
(custom-set-variables '(add-log-time-format (quote current-time-string)))最近のEmacsだとこの変数はdefaultで
'add-log-iso8601-time-stringになっているので
Sat Jan 6 00:17:18 2001 WATANABE Hirofumi <eban@ruby-lang.org>ではなく
2001-01-06 WATANABE Hirofumi <eban@ruby-lang.org>という形式になる。そのうち誰かがこの形式で入れるかもしれない。
map ch 1G:-r!env LANG=C date +"\%a \%b \%e \%X \%Y WATANABE Hirofumi <eban@ruby-lang.org>"^V^Mと書いてある。chで日付が入るだけだから大したことはない。でも便利。 ^Vと^Mは実際は制御文字なので注意.
viのcommandmodeではアルファベットのほとんどが使われてしまっているので、 mapで追加するときに悩むことがある。 vimではさらに増えてるので特にそうだ。 でもcとかdのように複数のstrokeが必要なcommandをprefixにして しまえばいいとある日気づいた。 chはもともと一文字前をcするという意味だけど、 10年以上viを使っていても一度もそんな操作をしたことがない。 だから潰しても問題ない。 vimを使うようになってv系でrangeを指定できるのも大きいかな。 オリジナルのviでcをmappingしようとすると
Too dangerous to map that
と怒られる。
using System; public class hello { public static void Main() { Console.Write("こんにちは" + "世界" + "\n"); } }これをUnicodeでセーブして(hello.cs)、コンパイル。
% csc hello.cs Microsoft (R) Visual C# Compiler Version 7.00.9030 [CLR version 1.00.2204.21] Copyright (C) Microsoft Corp 2000. All rights reserved. % ./hello こんにちは世界Windows 2000だとUnicodeなファイルをメモ帳で簡単に作れるけど、 Windows 95/98/Meだとそれなりのエディタが必要かもしれない。
Console.Write("こんにちは" + "表" + "世界" + "\n");お約束の"表"を追加してみた(hello-sjis.cs)。
% csc hello-sjis.cs Microsoft (R) Visual C# Compiler Version 7.00.9030 [CLR version 1.00.2204.21] Copyright (C) Microsoft Corp 2000. All rights reserved. % ./hello-sjis こんにちは表世界なんとエラーにならずにコンパイルできてしまった。 しかもちゃんと化けずに表示されるし。 ってことは一応マルチバイト対応もしてるんだなあ。
typedef void FILE;と定義してあったことだ。なつかしい。
% ls /usr/lib/mingw CRT_noglob.o crtmt.o dllcrt2.o libmingw32.a libmsvcrt.a crt1.o crtst.o libcoldname.a libmingwthrd.a libmsvcrt20.a crt2.o dllcrt1.o libcrtdll.a libmoldname.a libmsvcrt40.aいつのまにかlibcoldname.aがある。 元々はlibmoldname.aしかなかった。 このmはmingwのmを意味していたと思われるが、 msvcrtの意味に変わったらしい。cはもちろんcrtdllだ。 とするとspecsの中身が気になるが、libcoldname.aが使われていない。 gccのほうがまだ追従してない。 問題になるのは
% diff -u1 moldname-{crtdll,msvcrt}.def --- moldname-crtdll.def Sat Nov 18 08:12:18 2000 +++ moldname-msvcrt.def Sat Nov 18 08:12:18 2000 @@ -1,3 +1,3 @@ ; -; moldname-crtdll.def +; moldname-msvcrt.def ; @@ -36,2 +36,4 @@ +daylight DATA + dup @@ -114,2 +116,4 @@ tempnam + +timezone DATAのようにdaylightかtimezoneを使ったときだ、たぶん。 でもほとんど問題にならないだろう。
% gcc -msvcrt foo.c cc1.exe: Invalid option `svcrt'あ、こりゃだめだ。しょうがない-Zmsvcrtにしよう。
% gcc -Zmsvcrt foo.c gcc: unrecognized option `-Zmsvcrt'今度はcc1に渡らなかったので一応最後まで通った。 *cppに%{Zmsvcrt:-D__MSVCRT__}を追加してみる。
% gcc -specs=$PWD/specs -Zmsvcrt foo.cOK。これでなんとなくできそうな予感がしてくる. *1
-D_WIN32 -DWINNT -idirafter /usr/include/w32apiのオプションが外れる。まさに完全UNIX modeだ。
gcc -specs=specs.Zmscvrt -Zmsvcrt foo.cが可能になる。specs.Zmsvcrtを /usr/lib/gcc-lib/i686-pc-cygwin/2.95.2-6/specs へコピーすれば、どこからでも-Zmsvcrtできる。もとのspecsはbuiltin specsと同じなので保存しなくてもいい。
% cmp /usr/lib/gcc-lib/i686-pc-cygwin/2.95.2-6/specs =(gcc -dumpspecs)ところで-specsを指定したときに気になるのは最初にspecsを読んでることだ。
% gcc -specs=specs.Zmsvcrt -v Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/2.95.2-6/specs Reading specs from specs.Zmsvcrt gcc version 2.95.2-6 19991024 (cygwin experimental)これって差分だけでいいんじゃない? どうやらそういうことみたい。 ここではたと気づく。 じゃ-Zmsvcrtすら要らなくてspecsの指定だけで切り替えればいいじゃん. このspecsを指定したときはmsvcrt専用ということにして。 あとはcrossも考えて-lbmingwもlinkするようにしないとね。
checking whether getpgrp takes no argumentをチェックしてるところでハング。
% objdump -p conftest.exe | grep 'DLL Name' DLL Name: KERNEL32.dll DLL Name: cygwin1.dll DLL Name: crtdll.dllなぜかcygwin1.dllがlinkされてる。config.logを見ると
gcc -mno-cygwin -o conftest -Os conftest.c -lmと実行されている。一見問題なさそう。 が、ここはfork()を使ってるから、 そもそもconftest.exeは作られずエラーになるはず。 としたらもう原因は-lmしかない。
% cd /usr/lib % ls -l libm.a lrw-r--r-- 1 watanabe ruby 22 Dec 29 17:14 libm.a -> libcygwin.aうーむ。なにそれ? libm相当のものはCygwin DLLに含まれているから、 libm.aが必要ないというのわかるけど、これはひどい。
% ar rcv libm.aで空のlibraryを作ればすむ話なのに。
% ls -l libm.a -rw-r--r-- 1 watanabe ruby 8 Jan 8 15:50 libm.aしかもsymlinkよりもサイズは小さい。
cygwin*) rb_cv_have_daylight=no;; mingw*) LIBS="-lwsock32 -lmsvcrt $LIBS" ac_cv_header_a_out_h=no ac_cv_header_pwd_h=no ac_cv_header_utime_h=no ac_cv_header_sys_ioctl_h=no ac_cv_header_sys_param_h=no ac_cv_header_sys_resource_h=no ac_cv_header_sys_select_h=no ac_cv_header_sys_times_h=no ac_cv_func_times=yes;;defautl は
*) LIBS="-lm $LIBS";;だ。
gcc -mno-cygwin -c -DGAWK -I. -I. -DHAVE_CONFIG_H -Os -DDEFPATH='".:/usr/local/share/awk"' ./gawkmisc.c ./gawkmisc.c:31: gawkmisc.pc: No such file or directorygawkmisc.pcがないという。 なんか変なの。pc/Makefileを見るとここで makeするのが正しいってことなんだろうけど。
% cp -a pc/* . % make mingw32ってことらしい。このままだとCC=gccのままなのでCC='gcc -mno-cygwin' に変更。 main.cのenviron関係で
main.o(.text+0x1200):main.c: undefined reference to `_environ_dll'になるが
extern char **environ;の所為なので、他のplatformと同じように#if ... #end。 これでできた。-specs.msvcrtも試す。ok。
#!/bin/sh CFLAGS=-Os CC='i686-pc-cygwin-gcc' \ ac_cv_func_getpgrp_void=yes \ ac_cv_func_setpgrp_void=yes \ ../ruby-1.6.2/configure \ --target=i386-cygwin \ --host=i686-pc-cygwin \ --build=i586-pc-linux-gnu \ --program-prefix='' \ --includedir=/usr/local/cygwin-local/include \ --srcdir=../ruby-1.6.2 \ --cache=../config.cache-cygwin \ --with-tcl-dir=/usr/local/mingw \ --with-tk-dir=/usr/local/mingw \ --enable-tcltk_stubs \ --with-tcllib=tclstub83 \ --with-tklib=tkstub83 \ --with-opt-dir=/usr/local/cygwin-local \ --enable-shared/usr/local/cygwin-localというのがいかにも怪しいが、 /usr/local/cygwin/{include,lib}に他のライブラリ関係を置いてしまうと、 Cygwinのものと混ざってしまいバージョンアップとかがしづらくなるので分けた。 でも気にいらないので考え中。
% ls /usr/local/cygwin-local/{include,lib} /usr/local/cygwin-local/include: curses.h cursesw.h gd.h gdfontl.h ncurses.h readline zlib.h cursesapp.h cursslk.h gd_io.h gdfontmb.h ncurses_dll.h tcpd.h cursesf.h dbm.h gdbm.h gdfonts.h ndbm.h termcap.h cursesm.h expat.h gdcache.h gdfontt.h png.h ucl cursesp.h freetype gdfontg.h iconv.h pngconf.h zconf.h /usr/local/cygwin-local/lib: libcurses.a libgd.a libiconv.a libreadline.a libz.a libcurses.dll.a libgdbm.a libiconv.la libtermcap.a libexpat.a libgdbm.la libncurses.dll.a libttf.a libexpat.la libhistory.a libpng.a libwrap.a
#!/bin/sh CFLAGS=-Os CC='i686-pc-cygwin-gcc -specs=specs.msvcrt -Zbmingw' \ ac_cv_func_getpgrp_void=yes \ ac_cv_func_setpgrp_void=yes \ ac_cv_c_bigendian=no \ ../ruby-1.6.2/configure \ --target=i386-mingw32 \ --host=i686-pc-cygwin \ --build=i586-pc-linux-gnu \ --program-prefix='' \ --includedir=/usr/local/mingw/include \ --enable-shared \ --cache=../config.cache-mingw \ --enable-tcltk_stubs \ --with-tcllib=tclstub83 \ --with-tklib=tkstub83 \ --with-opt-dir=/usr/local/mingw/usr/local/mingwも同じような理由。 Tcl/TkはどちらもWin32版をlinkしている。 CygwinについてくるTcl/Tkは8.0なので日本語化パッチをあてないと、 日本人には辛いと思うし。なぜ未だに8.0のままなのか謎だ。
% ls /usr/local/mingw/{include,lib} /usr/local/mingw/include: X11 gd.h gdfontl.h ndbm.h tclDecls.h zconf.h dbm.h gd_io.h gdfontmb.h png.h termcap.h zlib.h expat.h gdbm.h gdfonts.h pngconf.h tk.h expat.h.bak gdcache.h gdfontt.h readline tkDecls.h freetype gdfontg.h iconv.h tcl.h tkIntXlibDecls.h /usr/local/mingw/lib: libexpat.a libgdbm.la libiconv.la libtermcap.a tclstub83.lib libexpat.la libhistory.a libpng.a libttf.a tkstub83.lib libgd.a libhistory.old libreadline.a libttf.la libgdbm.a libiconv.a libreadline.old libz.aTcl/TkはStubsを使うようにしてるので tclstub83 と tkstub83 だけあればいい。 ldは-lfooでfoo.libもlinkしてくれるようになっている。
--target=i386-cygwin \ --host=i686-pc-cygwin \ --build=i586-pc-linux-gnu \と与えている。 つまりクロスのツール類はi686-pc-cygwin-fooのような名前になっている ことをconfigureに教えているわけだ。 targetとhostだけでもよさそうだけど、 この二つだけだとbuildはhostと同じものになってしまいまずい。 buildを指定する必要がある。
ac_cv_func_getpgrp_void=yes \ ac_cv_func_setpgrp_void=yes \ ac_cv_c_bigendian=no \という環境変数の設定があった。 これは実行ファイルを作り、 実際にBUILD上で実行した結果から判断するテストで、 クロスの環境では不可能なものである。 これなしで進めると
cannot check getpgrp if cross compilingのようなメッセージを残してconfigureは異常終了してしまう。 このあたりは実際にやってみて エラーが起きたらconfigureを確認し変数を見つけ出すという作業になる。 Rubyの場合はこの3つを指定すればOK。 実際の値はnativeの環境から得るか自分で調べる。 getpgrp, setpgrpはvoidかどうかとbig endianかどうか。 このくらいなら移植する人には自明なはずだ。