MSYS2 (2)
Table of Contents
記念植樹で ruby
MSYS2を入れたので、記念植樹の第2段としてrubyを入れてみる。何、自分でコ ンパイルしてもいいんだけど、バグをトラックするのが面倒なので楽をするの さ。どんなのが有るか、とりあえず調べてみる。
$ pacman -Fy :: Synchronizing package databases... mingw64 5.4 MiB 1233 KiB/s 00:04 [#####################] 100% msys 1202.1 KiB 587 KiB/s 00:02 [#####################] 100% $ pacman -Fx bin/irb mingw64/bin/irb is owned by mingw64/mingw-w64-x86_64-ruby 3.1.3-2 mingw64/bin/irb.bat is owned by mingw64/mingw-w64-x86_64-ruby 3.1.3-2 usr/bin/irb is owned by msys/ruby 3.1.3-2
aptで言うapt-file search相当。インデックスを更新してから検索。msys版 とmingw64版が出てきたけど、選ぶならスピードが速いmingw64の方ね。
pythonも植樹
rubyが入ったなら、対抗上入れざるをえない。直接入れるのじゃなくて、gdb 経由ね。いわゆるお邪魔虫ね。gdbも入れるのは、mingw64版の方。
$ python Python 3.10.9 (main, Jan 14 2023, 21:23:14) [GCC 12.2.0 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> quit()
perlはデフォで入いっているから、これで揃いぶみだな。昔はよく頑張って入 れたものだ。
gdb
gdbも試運転しとく。ハロワの奴ね。
$ gdb -q a.exe Reading symbols from a.exe... (gdb) b main Breakpoint 1 at 0x1400014b1: file test.c, line 4. (gdb) r Starting program: C:\msys64\home\sakae\a.exe [New Thread 1180.0x21bc] Thread 1 hit Breakpoint 1, main () at test.c:4 4 printf("Hello MSYS2\n"); (gdb) disassemble Dump of assembler code for function main: 0x00007ff685ab14a4 <+0>: push %rbp 0x00007ff685ab14a5 <+1>: mov %rsp,%rbp 0x00007ff685ab14a8 <+4>: sub $0x20,%rsp 0x00007ff685ab14ac <+8>: call 0x7ff685ab1580 <__main> => 0x00007ff685ab14b1 <+13>: lea 0x7b48(%rip),%rax # 0x7ff685ab9000 0x00007ff685ab14b8 <+20>: mov %rax,%rcx 0x00007ff685ab14bb <+23>: call 0x7ff685ab1450 <printf> 0x00007ff685ab14c0 <+28>: mov $0x0,%eax 0x00007ff685ab14c5 <+33>: add $0x20,%rsp 0x00007ff685ab14c9 <+37>: pop %rbp 0x00007ff685ab14ca <+38>: ret End of assembler dump.
こうやって、MSYS2が肥大してく。今やWSLで入れてたDebianは使う事はないな。 削除もとえ、卒業させよう。
wsl --unregister Debian
蛍の光ーーー。また会う日まで。。。 こうして、MSとの距離を保つのさ。
gdbついでに前回やった一番簡単なGUI版をやってみる。一応コードを再掲。
$ cat hello.c #include <windows.h> int WINAPI WinMain(HINSTANCE ins, HINSTANCE previns, LPSTR cmdline, int cmd) { MessageBox(NULL, "Hello world.", "MBOX---------MBOX", MB_OK); return 0; }
$ gdb -q a.exe Reading symbols from a.exe... (gdb) b MessageBox Function "MessageBox" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (MessageBox) pending. (gdb) r Starting program: C:\msys64\tmp\a.exe [New Thread 12392.0xc34] [New Thread 12392.0x2084] [New Thread 12392.0x1cac] [New Thread 12392.0x2794] [New Thread 12392.0x870] [Thread 12392.0x870 exited with code 0] [Thread 12392.0x2794 exited with code 0] [Thread 12392.0x1cac exited with code 0] [Thread 12392.0x2084 exited with code 0] [Thread 12392.0xc34 exited with code 0] [Inferior 1 (process 12392) exited normally]
MessageBoxにBPを設定できずに素通りしてしまった。これってひょっとしてマ クロかな? さあ、どうするって3秒考えて、
gcc -E hello.c >exp.c $ tail -20 exp.c int __attribute__((__stdcall__)) WinMain(HINSTANCE ins, HINSTANCE previns, LPSTR cmdline, int cmd) { # 7 "hello.c" 3 MessageBoxA # 7 "hello.c" ( # 7 "hello.c" 3 4 ((void *)0) # 7 "hello.c" , "Hello world.", "MBOX---------MBOX", # 7 "hello.c" 3 0x00000000l # 7 "hello.c" );
ここまで判れば、後はヤルダケーーーって、いっこさん風。
$ gdb -q a.exe Reading symbols from a.exe... (gdb) b MessageBoxA Breakpoint 1 at 0x1400026c0 (gdb) r Starting program: C:\msys64\tmp\a.exe [New Thread 9996.0x1a70] [New Thread 9996.0x1cb4] Thread 1 hit Breakpoint 1, 0x00007ff81f29c2f4 in USER32!MessageBoxA () from C:\W INDOWS\System32\user32.dll (gdb) bt #0 0x00007ff81f29c2f4 in USER32!MessageBoxA () from C:\WINDOWS\System32\user32.dll #1 0x00007ff7e1d2148d in WinMain (ins=0x7ff7e1d20000, previns=0x0, cmdline=0x25cc6d34746 "", cmd=10) at hello.c:7 #2 0x00007ff7e1d22791 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexewin.c:70 #3 0x00007ff7e1d212ee in __tmainCRTStartup () at C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:272 #4 0x00007ff7e1d21406 in mainCRTStartup () at C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:193
後は醜いアヒルの子じゃなくて、糞石のそれをみておく。SKKの辞書に糞石っ て単語がなかったので即登録したよ。これからもよく使うだろうから。
(gdb) disassemble Dump of assembler code for function USER32!MessageBoxA: 0x00007ff81f29c2f0 <+0>: sub $0x38,%rsp => 0x00007ff81f29c2f4 <+4>: xor %r11d,%r11d 0x00007ff81f29c2f7 <+7>: cmp %r11d,0x37ff2(%rip) # 0x7ff81f2d42f0 0x00007ff81f29c2fe <+14>: je 0x7ff81f29c32e <USER32!MessageBoxA+62> 0x00007ff81f29c300 <+16>: mov %gs:0x30,%rax 0x00007ff81f29c309 <+25>: mov 0x48(%rax),%r10 0x00007ff81f29c30d <+29>: xor %eax,%eax 0x00007ff81f29c30f <+31>: lock cmpxchg %r10,0x38bb8(%rip) # 0x7ff81f2d4ed0 0x00007ff81f29c318 <+40>: mov 0x38bb9(%rip),%r10 # 0x7ff81f2d4ed8 0x00007ff81f29c31f <+47>: lea 0x1(%r11),%eax 0x00007ff81f29c323 <+51>: cmove %rax,%r10 0x00007ff81f29c327 <+55>: mov %r10,0x38baa(%rip) # 0x7ff81f2d4ed8 0x00007ff81f29c32e <+62>: orl $0xffffffff,0x28(%rsp) 0x00007ff81f29c333 <+67>: mov %r11w,0x20(%rsp) 0x00007ff81f29c339 <+73>: call 0x7ff81f29c620 <USER32!MessageBoxTimeoutA> 0x00007ff81f29c33e <+78>: add $0x38,%rsp 0x00007ff81f29c342 <+82>: ret
参考までに、展開されたexp.cは10万行近くあった。Windowsって、とんでもな い奴だな。本格的にやるなら、 MinGWでWindowsプログラミングを行う方法 とか、 MinGWでWindowsソフト開発(ウィンドウ編) こういうのを参考にすればいいんだな。
ruby ri
折角入れたのはいいんだけど、下記のようにriが知らんぷりだ。こんな現象は OpenBSDでも、経験してた。そう、ri用の原稿は別なパッケージになってたの だ。Rails屋さんとかには不要でしょうからね。
$ ri String Nothing known about String
色々探してみたけど、それっぽいのは無かった。で、ArchLinuxの /usr/local/share/ri以下をごっそりと貰ってきた。そしたら、一応反応する ようになった。但しlessの機能は働かない。なんで?
こういう時は強引に、
$ strace -o LOG ri String strace.exe: error creating process ri, (error 2)
手探り状態、もっと易しいので挙動確認。何せ相手はWindowsと陸続きの環境 ですから、どこに落とし穴が潜んでいるか、判ったものじゃない。
$ strace -o LOG ls LOG a.exe hello.c tmux-197609 $ less LOG --- Process 11020 created --- Process 11020 loaded C:\Windows\System32\ntdll.dll at 00007ff8209f0000 --- Process 11020 loaded C:\Windows\System32\kernel32.dll at 00007ff820210000 --- Process 11020 loaded C:\Windows\System32\KernelBase.dll at 00007ff81e720000 --- Process 11020 thread 6220 created --- Process 11020 thread 6132 created --- Process 11020 loaded C:\msys64\usr\bin\msys-intl-8.dll at 0000000430b30000 --- Process 11020 loaded C:\msys64\usr\bin\msys-2.0.dll at 0000000180040000 --- Process 11020 thread 3012 created --- Process 11020 loaded C:\msys64\usr\bin\msys-iconv-2.dll at 00000005603f0000 0 0 [main] ls (11020) ********************************************** 314 314 [main] ls (11020) Program name: C:\msys64\usr\bin\ls.exe (windows pid 11020) 103 417 [main] ls (11020) OS version: Windows NT-10.0 180 597 [main] ls (11020) ********************************************** :
いきなり団子じゃなくて、いきなりアプリだと問題ないのか。riってGem経由 で、色々やってるからなあ。それを追跡出来ないのか。
同じ事をArchLinuxでやって、途中で止めてみた。こういう方法でバックトレー スを取得できるのね。
:/usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:1355:in `close': Interrupt from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:1355:in `page' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:805:in `display' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:827:in `display_class' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:853:in `display_name' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:880:in `block in display_names' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:877:in `each' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:877:in `display_names' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:1511:in `run' from /usr/local/lib/ruby/3.1.0/rdoc/ri/driver.rb:397:in `run' from /usr/local/lib/ruby/gems/3.1.0/gems/rdoc-6.4.0/exe/ri:12:in `<top (required)>' from /usr/local/bin/ri:25:in `load' from /usr/local/bin/ri:25:in `<main>'
straceのログには膨大なgemの痕跡が残っていた。オイラーにとってはgem公害 だな。もっとクリーンなrubyが欲しい今日この頃。
そしてパッケージにruby-docsと言うのを見つけて入れてみたけど、有効にな らなかった。なんでだろう? 深く追求するのは、打ち切りしとく。
パッケージの探しかた
Repos から、好きな所を選んでいけばよい。
ocamlとかluaとか有るぞ。各種言語は、単独で提供されてるけど、それらを個 別にインストールすると取り回しが悪い。mingw64で集約してしまえば、管理 がラクチンでいいぞ。
perl,ruby,python,gaucheとかのREPLは、emacsから使うのが楽だ。 tmuxで複数のターミナルを動かしておく。端末を終了させる時に、 tmuxが動いているけど、いいかって聞かれる。いいよで応答。 後日、端末を開いて tmux a すれば、止めた所から続行できる。 生活の知恵だな。
知恵と言えば、上記のパッケージ一覧を見た時に、眩暈がするだろう。ブラウ ザーの検索機能を使って、絞り込むのが楽だ。目grepは禁止ね。目を労りましょ う。
pythonの使い所
こんな記事がでてた。 venvモジュールを使って仮想環境を構築するには モジュールが喧嘩するのを避ける方法なんだな。頭の切り替えが大変そう。 オイラーならOS提供ってかMSYS2/mingw64が供給してる奴だけを使うのが、賢 明だろう。沼には嵌りたくない。
上で紹介したパッケージのログをゆっくりと眺めたい。簡単なスクリプトを 作くった。そう、emacsでのスクリプト作成支援が使えるかの確認もこめて。 コードを書いて、C-c C-x のループ。段々とフィルターを増設する方式ね。
$ cat conv.sh #! /bin/sh # curl -s https://repo.msys2.org/mingw/mingw64/ >GW64 cat GW64 | grep 'zst<' | sed -e 's/<.*">//' | sed -e 's!</a>!!' | sed -e 's/mingw-w64-x86_64-//'
curlで一気にパイプしてもいいんだけど、ネットに負担をかけないように、一 旦ログに落としてからやってる。URLの最後に / を忘れない事。
ネットに負担をかけない、なんてサラッと言てるけど、これって、犬HKのチコ 番組でCO2削減のため電球一個にしてますってのと同じ構図だな。まやかしだ。 本当に削減したいなら、再放送はやめて停波しろよ。そしたら大幅にCO2の削 減ができるぞ。オイラーなら、OSのアップデートを月に一度にするとか。。
$ ./conv.sh | grep python : python-lzo-1.12-2-any.pkg.tar.zst 23-Oct-2020 08:10 27K python-lzo-1.12-3-any.pkg.tar.zst 16-Jul-2021 17:24 26K python-lzo-1.14-1-any.pkg.tar.zst 09-Feb-2022 08:57 26K python-lzo-1.14-2-any.pkg.tar.zst 11-Jun-2022 14:45 26K python-pip-21.3-1-any.pkg.tar.zst 24-Oct-2021 12:25 2M python-pip-22.2-1-any.pkg.tar.zst 26-Jul-2022 17:27 2M python-pip-22.3-1-any.pkg.tar.zst 20-Oct-2022 11:03 2M python-pip-23.0-1-any.pkg.tar.zst 31-Jan-2023 16:27 2M
Webから見た時は、随分沢山のパッケージが提供されてるかと思ったら、過去 のもので、水増しされてるだけだった。
オイラーが嬉しいpythonの機能。
sakae@atom MINGW64 /usr/share/doc/cygwin-api $ python3 -m http.server 80 Serving HTTP on :: port 80 (http://[::]:80/) ... ::ffff:127.0.0.1 - - [07/Feb/2023 05:45:13] "GET / HTTP/1.1" 200 - ::ffff:127.0.0.1 - - [07/Feb/2023 05:45:14] "GET /docbook.css HTTP/1.1" 200 -
怖い事に80番で起動できちゃう。そして、普通にIPv6が利用されてる。これっ て、Windowsならではなんですかねぇ。
Windows GUI
# for Windows GUI SRC=window.c RC=menu.rc OBJS=$(SRC:.c=.o) OBJS+=$(RC:.rc=.o) PROG=a.exe CC=gcc MENU=windres SED=sed 's/\\/\\\\/' CFLAGS=-Wall -O3 LDFLAGS=-mwindows RM=rm %.o: %.c $(CC) $(CFLAGS) -o $@ -c $< %.o: %.rc $(SED) $(RC) | $(MENU) -o $*.o .PHONY : all all: $(PROG) $(PROG): $(OBJS) $(CC) $(OBJS) $(LDFLAGS) -o $@ .PHONY : clean clean: $(RM) -f $(OBJS) $(PROG)
雛形のファイル。これが有ればスイスイだな。 コピペさせて貰ったんだけど、その途中で重大な事に気付いてしまった。ファ イル名は大文字も小文字も区別しないっていう仕様、しようも無い仕様だ。 DOS時代からです。DNAなんです。こればっかりは変更できません。