2022/08/22(月) [n年前の日記]
#1 [prog][windows] msys2 + MinGW-w64でスクリーンセーバをビルドしようとしてハマった
以下で紹介されている、MinGW用のスクリーンセーバサンプルをビルドしてみたくなった。環境は Windows10 x64 21H2。
_よしいずの雑記帳 スクリーンセーバーの作り方
以下の2つのファイルをコピペして作成。文字コードは UTF-8N にした。(※ 2022/08/23追記。文字コードはSJISにしたほうが良かったのかもしれない。)
_scrnsave.c
_resource.rc
また、Makefile も作成した。
_Makefile
結論を先に書いておくけど、msys2 + MinGW-w64 ではダメ。MinGW でビルドしましょう…。
_よしいずの雑記帳 スクリーンセーバーの作り方
以下の2つのファイルをコピペして作成。文字コードは UTF-8N にした。(※ 2022/08/23追記。文字コードはSJISにしたほうが良かったのかもしれない。)
_scrnsave.c
_resource.rc
また、Makefile も作成した。
_Makefile
screensv.scr: screensv.o resource.o gcc screensv.o resource.o -lscrnsave -mwindows -o screensv.scr screensv.o: screensv.c gcc -c screensv.c -o screensv.o resource.o: resource.rc windres resource.rc -o resource.o .PHONY: clean clean: rm -f *.scr rm -f *.o
結論を先に書いておくけど、msys2 + MinGW-w64 ではダメ。MinGW でビルドしましょう…。
◎ msys2 + MinGW-w64ではスクリーンセーバをビルドできない :
msys2+ MinGW-w64 でビルドしようとしたら失敗した。screensv.o と resource.o は生成されたけど、リンクエラーが出る。
スクリーンセーバ作成に関係してくるファイルは以下だろうか…。ちなみに自分の環境では msys2 を C:\msys64\ にインストールしてある。
scrnsave.h はそれらしい内容が書かれているように見えるけれど。libscrnsav*.a は、どちらもファイルサイズが990Byte と異様に小さい上に、全く同じサイズというのが気になる。
余談。巷の関連記事では、スクリーンセーバの作成には scrnsave.h と scrnsave.lib が必要と書いてあるのだけど、それは Microsoft Visual C++用の話のようで。MinGW の場合は libscrnsave.a か libscrnsavw.a が必要になるらしい。最初、そのことが分からなくて、scrnsave.lib を探して「無いな…MinGWでは作れないのかな…?」と勘違いしてた。
さておき。msys2 + MinGW-w64 でリンクエラーが出る原因についてググっていたら、以下の話を見かけた。
_Re: [Mingw-w64-public] [mingw-w64:discussion] No symbols in libscrnsave.a; source file scrnsave.c c | MinGW-w64 - for 32 and 64 bit Windows
_MinGW-w64 - for 32 and 64 bit Windows / Discussion / Help: No symbols in libscrnsave.a; source file scrnsave.c commented out
_MinGW-w64 - for 32 and 64 bit Windows / Bugs / #351 Scrnsave lib empty
おそらくだけど、「libscrnsav*.a の元になる scrnsave.c が全部コメントアウトされているけれどこれってどういうこと?」と言っているのだろう。ナニソレ、マジかよ。
MinGW-w64のソースコードであろう、mingw-w64-v10.0.0.zip をDLして解凍して中を覗いてみた。
_MinGW-w64 - for 32 and 64 bit Windows download | SourceForge.net
以下がスクリーンセーバ関連のファイルだろうか。
scrnsave.c を開いて確認してみたら、たしかに #if 0 - #endif で全内容がコメントアウトされていた。これではリンクできるわけが無い…。なんでこんなことをしたんだ…。
アレかな。メンテナの方々が「今時スクリーンセーバなんて作るやつ居ねえだろ」と勝手に決めつけてやらかしたのかな…と邪推。まあ、MinGW から fork して MinGW-w64 を作り始めた時に、まずは全体のビルドが通る状態にすることを優先していただろうし。そのまま放置されたのかも…。
そんなわけで、msys2 + MinGW-w64 では、スクリーンセーバをビルドすることはできないと分かった。
※ 2022/08/23追記。github にも scrnsave.c があった。1行目から #if 0 があることが分かるかと。
_mingw-w64/scrnsave.c at master - Alexpux/mingw-w64
$ gcc --version gcc.exe (Rev1, Built by MSYS2 project) 12.2.0 Copyright (C) 2022 Free Software Foundation, Inc. ... $ windres --version GNU windres (GNU Binutils) 2.39 Copyright (C) 2022 Free Software Foundation, Inc. ... $ make --version GNU Make 4.3 このプログラムは x86_64-pc-msys 用にビルドされました Copyright (C) 1988-2020 Free Software Foundation, Inc. ...
$ make gcc -c screensv.c -o screensv.o windres resource.rc -o resource.o gcc screensv.o resource.o -lscrnsave -mwindows -o screensv.scr C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: screensv.o:screensv.c:(.text+0x229): undefined reference to `DefScreenSaverProc' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): in function `main': C:/M/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain' collect2.exe: error: ld returned 1 exit status make: *** [Makefile:2: screensv.scr] エラー 1
スクリーンセーバ作成に関係してくるファイルは以下だろうか…。ちなみに自分の環境では msys2 を C:\msys64\ にインストールしてある。
- C:\msys64\mingw64\include\scrnsave.h
- C:\msys64\mingw64\lib\libscrnsave.a
- C:\msys64\mingw64\lib\libscrnsavw.a
scrnsave.h はそれらしい内容が書かれているように見えるけれど。libscrnsav*.a は、どちらもファイルサイズが990Byte と異様に小さい上に、全く同じサイズというのが気になる。
余談。巷の関連記事では、スクリーンセーバの作成には scrnsave.h と scrnsave.lib が必要と書いてあるのだけど、それは Microsoft Visual C++用の話のようで。MinGW の場合は libscrnsave.a か libscrnsavw.a が必要になるらしい。最初、そのことが分からなくて、scrnsave.lib を探して「無いな…MinGWでは作れないのかな…?」と勘違いしてた。
さておき。msys2 + MinGW-w64 でリンクエラーが出る原因についてググっていたら、以下の話を見かけた。
_Re: [Mingw-w64-public] [mingw-w64:discussion] No symbols in libscrnsave.a; source file scrnsave.c c | MinGW-w64 - for 32 and 64 bit Windows
_MinGW-w64 - for 32 and 64 bit Windows / Discussion / Help: No symbols in libscrnsave.a; source file scrnsave.c commented out
_MinGW-w64 - for 32 and 64 bit Windows / Bugs / #351 Scrnsave lib empty
おそらくだけど、「libscrnsav*.a の元になる scrnsave.c が全部コメントアウトされているけれどこれってどういうこと?」と言っているのだろう。ナニソレ、マジかよ。
MinGW-w64のソースコードであろう、mingw-w64-v10.0.0.zip をDLして解凍して中を覗いてみた。
_MinGW-w64 - for 32 and 64 bit Windows download | SourceForge.net
以下がスクリーンセーバ関連のファイルだろうか。
- mingw-w64-v10.0.0\mingw-w64-crt\libsrc\scrnsave.c
- mingw-w64-v10.0.0\mingw-w64-headers\include\scrnsave.h
scrnsave.c を開いて確認してみたら、たしかに #if 0 - #endif で全内容がコメントアウトされていた。これではリンクできるわけが無い…。なんでこんなことをしたんだ…。
アレかな。メンテナの方々が「今時スクリーンセーバなんて作るやつ居ねえだろ」と勝手に決めつけてやらかしたのかな…と邪推。まあ、MinGW から fork して MinGW-w64 を作り始めた時に、まずは全体のビルドが通る状態にすることを優先していただろうし。そのまま放置されたのかも…。
そんなわけで、msys2 + MinGW-w64 では、スクリーンセーバをビルドすることはできないと分かった。
※ 2022/08/23追記。github にも scrnsave.c があった。1行目から #if 0 があることが分かるかと。
_mingw-w64/scrnsave.c at master - Alexpux/mingw-w64
◎ MinGWでビルド :
msys2 + MinGW-w64 ではなく、MinGW + msys でビルドを試してみた。
必要なファイルは以下だろうか。ちなみに自分の環境では、MinGW を D:\MinGW\ にインストールしてある。
すんなりビルドが通った…。
出来上がった screensv.scr を右クリック → Test、を選んだら、画面一杯に丸が描画され続けた。また、マウスを動かしたら終了した。
MinGW でビルドした .exe や .scr は32bit版だろうから…。Windows10 64bit版を使っているので、C:\Windows\SysWOW64\ 以下に screensv.scr をコピーして動作確認した。正常に動作してくれた。
ただ、スクリーンセーバ設定画面で、「設定」をクリックすると、文字化けしたメッセージが表示されてしまう。
> gcc --version gcc (MinGW.org GCC Build-2) 9.2.0 Copyright (C) 2019 Free Software Foundation, Inc. ... > windres --version GNU windres (GNU Binutils) 2.32 Copyright (C) 2019 Free Software Foundation, Inc. ... > make --version GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. ...
必要なファイルは以下だろうか。ちなみに自分の環境では、MinGW を D:\MinGW\ にインストールしてある。
- D:\MinGW\include\scrnsave.h
- D:\MinGW\lib\libscrnsave.a
- D:\MinGW\lib\libscrnsavw.a
すんなりビルドが通った…。
出来上がった screensv.scr を右クリック → Test、を選んだら、画面一杯に丸が描画され続けた。また、マウスを動かしたら終了した。
MinGW でビルドした .exe や .scr は32bit版だろうから…。Windows10 64bit版を使っているので、C:\Windows\SysWOW64\ 以下に screensv.scr をコピーして動作確認した。正常に動作してくれた。
ただ、スクリーンセーバ設定画面で、「設定」をクリックすると、文字化けしたメッセージが表示されてしまう。
[ ツッコむ ]
以上です。