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なんです。こればっかりは変更できません。