mieki256's diary



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
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 は生成されたけど、リンクエラーが出る。

$ 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 でビルドを試してみた。

> 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 をコピーして動作確認した。正常に動作してくれた。

ただ、スクリーンセーバ設定画面で、「設定」をクリックすると、文字化けしたメッセージが表示されてしまう。

以上、1 日分です。

過去ログ表示

Prev - 2022/08 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project