GNU C/C++ Compiler for Win32を使う: last modified at 1996.Dec.24 0. Abstruct   GNU C/C++ for Win32をWindows95に入れてみましたのでレポートします。半ば同時  進行で書いた、殆ど日記であることをお断りしておきます。   なお、文中で出てくるソフトは現在ではバージョンアップしていたり、名前の変更や  機能アップもあるかもしれません。   なお、用語に付いての詳解はしません。   ちなみに当方、基本的にDOSな人でして、UNIX系は良く知りません。何かまずいことを  書いていたら教えて下さい。一応、できるだけのファイルは読んだつもりなんですが、  大ボケかましている可能性がありますので。   後、入手先が明示されてないアプリは、明示してないのではなくて明示できない  のです。どっかの雑誌のCD-ROMだとか、会社のサーバにあったりe-mailに添付されてた、  はては何時からかHDD内に鎮座してたという代物ですんで。 1. Install   先ずURLをば。どうやってここにたどり着いたかは不明だけど(ぉぃ!)。  気が付いたらBookmarkに入ってたのだ。多分、上から辿ってって下を見付けたんでしょ。   http://www.cygnus.com/misc/gnu-win32/   http://www.fu.is.saga-u.ac.jp/~colin/mingw32-goal.html  (どちらもルートのURLではありません、多分)   上記から必要そうなページを読んで、最少限必要という以下をダウン。  five_tar_.gz  mingw32-0_1_1_tar.gz  two_tar.gz  windows32api-0_1_2_tar.gz Total: 5,914,624 bytes --- 会社でftpできるのがありがたいぞ(^_^;;   でもね、tarがないの(;_;)。結局、書籍「PACK13000」のCD-ROMからDOS版の奴を  拝借して展開。こいつはDOS版なので当然Long Filename (LFN)に対応してない。   さて。rootで展開しろ、とのお達しがあるが恐いので適当なディレクトリ下で  展開してから移動することにした(幸い、相対Pathでアーカイブされてた)。   tar -xvf foo.gz ってな具合。 (-tvfでアーカイブ内ファイルの一覧が出る)   で、全部展開してからreadme.txtを読むとLong Filename対応のWinZipを使え、  と書いてある。   みゅ〜。アーカイブの中にそーゆー文章を入れてもらってもだね……。それとも  あたしが見落としたのか?(こっちの公算が大)   もちろんここで再展開しても良かったのだが、根がずぼらなのでこのままGo!と  する(日頃の展開にはfreeのLhasaを使用してるせいもある。作者に感謝!)。   良く考えたら、http://www.symantec.comから落としたNorton Navigatorの試用版  でも良かったかもしれない。DMF FDをも作成可能な優れものですぞ。ただ、英語版の  Windows95でないとDMF FDへの書き込みができないけど。どうして日本語Windows95では  わざわざDMFであることを確認してまで書けなくしたのさ>Microsoft   まぁその気になればDMF ID文字列を変更するだけで書けるけどね。約1.6MBのFD。  便利と思うかね?   だけど、1.44MBより役に立たないのだ、これがまた。やってみれば分かる。今はGCCの  話なので書かない。試したければNorton Navigatorを使ってみること。   製品版だって高くないから、いきなり買っても損はない。あ、ただし英語版にする  こと(何時だってこの手のtoolは英語版が最新版だから)。設定変えれば日本語も通るし。 2. Setup   先のURLにやり方とか書いたページがある。あるのだが、同じマシンでブラウザを開き  つつ作業するのも辛いものがある。そこで会社の小型マシンでIEを使い、内容を読みも  せずに一連のページをダウン。自宅にマシンを持ち帰って「Proxyを使わない」に設定  し直す。   IEはこうすることでローカルにページを表示できるので便利。NNは同等の事をする  ためのFreeだかShareだかのアプリがあるので、きっとこういう真似はできないのかな?   NNには頑張って欲しいものだと個人的に思っている(が、俗物たる私はタダのIEを  使ってしまうのだった---でもe-mailはIEでは恐い(IEの文字コード問題は直ったの?)ので  会社では主にNN使ってますけど)。   で。use-setup.html (先に紹介したURLのhtmlファイル名)の階層図と展開後の階層構造が  一致してない。英語力がないもんだから、ドキュメントが良く理解できない。不明な単語を  PDICで訳して見るが、いかんせん文章量がありすぎる。   PDIC/PDICWはFreeの英日単語翻訳ソフト。インクリメンタルサーチができるのでとても  便利。辞書もFreeなせいか、極希に間違った単語とかもあるがご愛敬。   PDICは32 bit版もできたという噂を聞いたが、現状で別段不満もないのでアップデートの  努力は全くしてない。   でも手当たり次第に辞書をマージしてしまったのでかえって使い勝手が悪くなって  しまった。辞書の間違いに気づいた時もメモしてればそれなりにフィードバックもできた  はずだけど、当時、仕事で尻に火が付いてたから記録を取ってなかったし。   この辺り最近のFEPと同じ。辞書がでかけりゃ良いってもんぢゃないでしょうに……。  候補一覧に訳の分からんのがずらっと並ぶぐらいなら自分で単語登録した方がまし。   雑誌のライター諸氏や漢字を知らないユーザよ、妙な評価をしないでくれ。こっちは  迷惑してんだから(故にAtok10やWX-GだとかMSIME97には余り興味なし)。   確かにAtok7からWX2+に乗り換えた時には驚愕しましたけどね。賢いFEPとはなんて  凄いんだ!こんなに自分が漢字変換でストレス受けてたとは思わなかった!!!って程  感激しましたから。   でもま、それはAtok7が学習内容をある日突然忘れる(信じ難いことにリングバッファで  はなかったのだ)という設計だったってことが大きい気がするが。   詩を書くこともある(意外でしょ?>私を個人的に知っている人)当方としては、物忘れ  しないATOK7にユーザ辞書の組み合わせ、つまりWX2+で必要充分だったのだ(意図的な言い  回しを阻害されるAI変換の類は却下なのである)。   …話がずれた。で、良く良く検討してからファイルやフォルダを移動する。秋月の電子  キットと同じだ。説明と実際が食い違っていてもうろたえてはならない。これぐらい何とか  できる技量がなければ初めから手を付けてはいけないのだ。   しかし。リソースを付加するには別アーカイブのプログラムが必要だとか、Import  ライブラリの構築が必要だとか、不吉なことが書いてあるなぁ。   昔、Linuxを386SX/25MHz + 4MB Memoryに入れてXがすかすか動くのを目の当たりにして  (勘違いかもしれない。メモリは8MBだったかも。だが決して16MB以上のはずはない)、  Windows 3.1のメモリの馬鹿喰いって、一体何なの?とか思ったものの、OSのバージョン  アップをするのに、互いに矛盾するパッチを見比べながらKernelの再コンパイルが必要とかで  挫折した前科があるのだ。当時(今もだ!) news見れる環境になかったし。   Readmeを見付けたら片っ端から読む。UnixとDOSの改行コードの差異から結構悲惨。だが、  それは予想されていたこと。nkfで処理しても良いんだろうが、手動で読みながらやってしまう。   文字コード自体は違わないからそれができる。UnixでもASCiiが通用してて良かった。これが  EBCDICだったら絶対にコード変換が必要だ。   待てよ。…う。Vzとか、いや単にtype|moreでも問題無く表示するではないか!あぁ、くそ。  おいらったらアホちゃうか(;_;)   まぁ良いや。苦労したくないならVC++なりBC++を買ってくれば済む話ではないか。  Windows95を使いながら何言ってるんだと思う人も多いだろうが、あたしゃMicrosoft製品は  避けたいのだ。だからVC++は自宅マシンで使いたくないんだ(会社ではしょうがないけど)。   BC++?あ、まぁその(しどろもどろ[^^;;])。そうそう。Delphiは優れた言語だと思いましたよ。  '96/10月で試用期限が過ぎちゃいましたけど。   いかん。またずれた。そうそう。nkfはunixな人なら知っている(と思うけど?)文字コード  変換フィルタ。DOSにも色々な人が移植しているみたい。rot13をサポートしてるのが便利。  あ?何の話だっけ。   ええと?windows32 APIのアーカイブは\usr\win32の下に展開せよ、か。多分、こいつだ  とあたりを付け、windows3\以下をwin32に被せる。   win32の下にlibがないなぁ。jamfileかdlltoolでlibを作る必要があるって?それって  何さ?use-setup.htmlの指示に従い、*.exeや*.aを移動。しかしcygwin.dllをsystemに?  そういう.dllに依存したくはないのだが。どうすべぇ。とりあえず移動。   readme.txtによれば、できた奴(*.exe)はcygwin.dllを必要としないが、gccを走らすには  (この.dllが)必要とのこと。なる程。   良く読めばjam.exeなるものの記述もある。ふぅん。後で落とそかな。 3. Create library   環境変数をautoexec.batにセットした関係で再起動。ところで、うちのDOS窓、実は  ShellがCommand.comじゃぁない。Ndos.com (Sharewareの4DOS.comのOEM)だったりする。  昔のNorton Utilityに付属してた奴だ。コマンドラインの補完はもちろんAliasやら  何やらで下手なファイラー使うよりよっぽど便利。   で、こいつのDefaultでの環境変数サイズが512 byte。何が言いたいかといえば、  Command.comのDefaultでは足りないよってこと。/Eオプションだっけか?DOS窓なら  プロパティで何とかなるかもしれないけど、autoexec.batで全ての環境変数を定義する  ならきっと細工がいると思う(確認する気は全然ないけど。何故ならCommand.comを使う  気が起きないから)。   ちなみにうちの環境で656 byte使っている。だから768 byte程度確保するとOKかも?  (ん?何か矛盾するな。NdosのDefaultって1024 byteだっけ?)   さて。例によってhello world!を書いて  gcc -o foo.exe foo.c   おや?テンポラリが開けないって?こりゃあれだな、あれ。テンポラリをルート'c:\'に  しとくと誤動作するって奴だ。単純に'\'を付けると、'c:\\'になっちゃうって問題。   かと言ってtmpを'c:'にしとくとC:のカレントディレクトリにテンポラリを開くアプリが  あったりするし。   逃げ手としては'c:\.'という手もないこともないが、Netscapeはこれでもだめだった  ような気がする。ま、それはともかく。面倒だからWindows95のデフォルトに戻すか。  set tmp=c:\win95\tempとする(もちろんだが、うちのOSR2はカスタムインストールである。  普通はc:\windows\tempだが。MSが充分な資料を公開してくれてれば別にdefaultに任せても  良いのだが、そうでない以上はなるべくこっちを異常な環境下に置かなくてはならんのだ。  --- 異常な環境でも支障なく動作すれば、まともな環境では更に正常に動作するものさ。  もちろん、「例外のない一般法則は存在しない。この法則も例外ではない」のだが……)。   時に、何故set tempじゃないかって?unix系でしょ?tempじゃなくてtmpを参照するに  違いないのだ(ちなみにこの洞察は正解でした)。   蛇足だけど、テンポラリをc:\にしておきたい理由は、ゴミファイルの有無がすぐに  分かるから。普通見ない所にtempを設定しておくと、やっぱりtempにごみが溜まるのよ。  もちろんautoexec.batで自動削除すれば済むんだけどね。蛇足終わり。   さてとライブラリを作っておくか。\usr\win32\sourceに行く。作り方は書いてある。  dlltool --dllname %1.dll --def %1.def --output-lib \usr\lib\lib%1.a -k   で作るらしいが。ちょっと!.defって50以上あるやんけ。forでまわすバッチを...っと  いかん。'.def'付きで指定できんではないか。for %f in (*.def) do echo %fとかで  展開すると%fには必ず拡張子が付いてしまう。   こんな時にはbriefだ。DOSのエディタ。既にBorland (と思った)に買収されてしまって  単体では買えなくなってしまった(英語版って、まだ買えた?)が、超優れもの。英語版なら  テキスト画面が許す限りの広さでeditできる。   うちの場合、800*600フルで(LCDマシンなんです)テキスト画面をセットするツールを  作ってある(C&Tの特定VGAチップに依存する機能を使用しているので公開はしてない)ので  100*75画面だ!   英語版だから日本語のコメントとか化け化けになるが、GNU関連ファイルは元々英語だし、  私はソース中に日本語入れないから関係ない。   briefは'd' + ' 'と入力すると勝手に   do   {     _←ここ、カーソルね   } while();   とまでやってくれる親切設計。もちろん'{'の位置はカスタマイズ可能(defaultはK&Rだった  かも)だ。マクロはInteger C、あるいはlisp-likeな文法を持っている(元々はlisp-likeな  マクロのみだったのだが、後のバージョンでC-likeなマクロ形式もサポートした)ので記述も楽々。   brief-likeなWindowsベースのeditorとかもあるらしいが私は使ったことがない。  VzやNotePadで間に合わない時はhttp://www.windows95.comで見つけたfreeのNextPadという  エディタを使っていたりする。癖がないのでNotePadの代わりには丁度良いのだ。  (統合環境下のエディットって、どうも好きになれない。だって重過ぎ。必要なら使うけど、   基本はコマンドラインからとか思う)   …Vz Editor、説明は不要と思うがちょっとだけ。日本語DOSの世界で発売以来、あっと  いう間に老舗のMifes、Final、Red辺りより有名になったフル・アセンブラの軽快Editor。   Vzの長所と短所がちょうどBriefの逆になっているので両方とも手放せない。  (1行の扱い、ファイラーの有無、正規表現、etc.)   大体、日本語文書=Vz or NotePad、ソース=Brief。Windows依存のEditorも色々試したけど、  未だ基本的にはこういう組み合わせ。   また脱線した。さて。  dir/b *.def > DoDll.bat   でファイルを作ってキーマクロ機能で'.def'を削ってdll.batを呼び出すように行毎に  変更。リピート機能もbriefにあるから楽勝。  call dll FOO  call dll BAR   ...   てな感じに直す。あ、dll.batはdlltool...以下の行が書いてあるだけのバッチね。   で。再コンパイル。う。mingw32がリンクできないって?そんなファイルはないぞ!?  消しちゃった?それともアーカイブが足りない?   待て待て。落ち着け。これは未だ作ってない、ってのが正解だろう。'mingw32'が  文字列として含まれるファイルを探す。あった。\src\mingw32\libの中に。  mk.batを実行。   …おぃ。includeファイルがWindows32の下にない、だと?当然だ。そんなディレクトリは  ない!win32ならあるけどさ。   どっちを直すべきだろう。Windows32といえば8文字を超える。つまりLFNだ。ここは  win32にすべきだろうな。ソースを修正しよう。幸い、main.cだけだから大した手間じゃない。   …や、違う。環境変数はwin32になっている。慌ててはだめだ。ええと。  \usr\win32\headers\windows3   だな。問題は。DOS版のtarを使ったためだ。windows32とする。で、ええくそ。またLFNか。  functions.hとstructures.hか。名前を変えて...どうだ?  AsciiFunctions.hとUnicodeFunctions.hだと?はいはい。   よし。では再度。  gcc -o foo.exe foo.c   …moldnameがないだと?う〜、ワンワン。   readme.txtに何かごちゃごちゃ書いてあるけど、oldnameが別にあるからmoldnameという  名前になっているって?で、そのmoldnameは何から作るだよ?   moldnameでサーチ。ふむ。\src\mingw32\libのoldnames.cとjamfileか。   しかしこのjamfileってどーやって使うんだ?まぁ良い。今はmoldnameだ。さっきみたいな  mk.batはない。だがoldnames.cを見ると、あっしはlibmoldname.aのソースだ、と書いてある。   ふむ。これは他のmk.batに書いてある内容と同様にやれば良いはずだ。  gcc -c -o OLDNAMES.o OLDNAMES.C   あらら。山のようなエラー。ctype.h内でwint_tが無効だと?そいつの定義はstddef.hだ。  でもC++でないとwint_tは定義されんぞ?   とりあえずwint_tの定義を入れて...warningとerrorか。ほんとにこのソースで良いのか?   待て。libんとこにlibmoldn.aがあるぞ。これってひょっとして?libmOldName.aに変える。  う〜む。crtdllがリンクできんか。もうイヤ。まぁ前進はしてるわな、少なくとも。   crtdllは...\src\mingw32\crtdllにcrtdll.defがあるっと。こいつはmk.batがあるから...  で、今度こそ。。。  gcc -o foo.exe foo.c   やったね!(^_^v   …debugで実行すると'DOS modeじゃ動かん'と主張して終わるけど、そのまま実行だとだんまり?  戻ってはくるけど。みゅ〜(?_?)   そーいえば何か書いてあったな……デフォルトはGUIモードになるとかかんとか。  gcc -o foo.exe foo.o -luser32 -Wl,--subsystem,console←この行、'I'はありません。全て'l'   あぁ、こうか。よし成功!すったもんだで'hello world!'に成功。ふぅ。   次はGUIアプリだ。が、rcl_exe.gzをダウンしなくちゃ。。。 4. GUI applications   さて。取ってきたのは: cvtres_tar.gz 16,883 cvtres.exe .resを.oに mingw32-rcl-1_6_3_tar(1).gz 176,239 rcl.exe .rc/.resを.res/.exe/.dllに rcl_exe.gz 86,084 CRC ERROR! (;_;)←解凍不能 res2coff_tar.gz 15,353 res2coff.exe .resを.oに   う〜む。よくわからん。いらないもんもあるような?   ま、いいか。さてと。テストだ。SDKのGENERICを試しに...っと、いけませんねぇ。  こいつのmakefileは当然VC++で動作するようになっているはず。先ず書き直さんと……。  ぎょっ。いきなり!include と書いてある。ぁぅぁぅ。   当然、SDKを入れてないこっちのHDDには存在しない。SDKのCDには当然ある。  で、win32.makを見ると……。   コンパイルオプションやらなんやらか。こいつをみんなgcc向けに直すのはちょいと  ヤだな。うむ。通らばリーチ!何も変更とかせずに:  gcc -c generic.c   おや。エラーも何もなしにgeneric.oができたぞ。んじゃあ。  rcl -i generic.rc -r generic.res   winver.hがない、ときたもんだ。しかしrclのドキュメントにゃ、versioninfoは未だ  サポートしてない、とある。仕方ない。本家SDKのrcをここでは使おう。   genericのmakefileはこうだ。 $(rc) $(rcflags) $(rcvars) /fo $(PROJ).res $(PROJ).rc   win32.makではこうなっている。   !IFDEF NO_ANSI   noansi = -DNULL=0   !ENDIF   rcflags = /r   rcvars = -DWIN32 -D_WIN32 $(noansi)   !IF "$(APPVER)" == "4.0"   rcvars = $(rcvars) -DWINVER=0x0400   !else   rcvars = $(rcvars) -DWINVER=0x030A   !ENDIF   多分、rc /r -DWIN32 -D_WIN32 -DWINVER=0x400 /fo でいいんでないかい?  う。rcdll.dllもいるのか、実行に。え?windows.hがない?思わず環境変数を見直す。  set   はん。unixの流儀とwinの流儀でinclude fileの定義が違うのね。つまり:  set include=c:\usr\win32\headers   こいつが必要。お?limits.hもない?くそ。  set include=c:\usr\win32\headers;c:\usr\include   あ、winver.hがない...う〜む。これはf:\mstools\includeか。SDKの中だ。とりあえず  カレントディレクトリに入れて、と。でもこれならrclでも良いんとちゃうやろか?   rcとrclで.resを作ってみる。どっちも「再定義された」のワーニングで山。で、できた  .resの大きさが違うぞ(rclで作った方が小さい)。  res2coff -i GENERIC.RES -o GENres.o   あう。rclで作った.resだとフェータルエラーだ。rcで作った奴ならOK。  gcc -o generic.exe generic.o genres.o   ぎゃっ。未解決のシンボルが山のよう。ライブラリか?んじゃmakefileを見る。  gcc -o gene.exe GENERIC.O GENRES.O -luser32 -lversion   む。未解決が4つに減ったぞ。こいつはどれだ?win32.makを見れば、  baselibs = kernel32.lib $(optlibs) advapi32.lib  winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib   ……   結局、 -luser32 -lversion -lgdi32だけでOK。さぁて?   おぉ!!ちゃんと動くではないかぁぁ!!!感激。あ。余計な情報を削って。。。  strip generic.exe   ふむ。結果:generic.exe 14,336 byte。VC++で作ったのとどっちが大きいかな?   …VC++ 4.0で'nmake nodebug=1'したら27,136 byteになったぞ!?何となくVC++の  方がでかいような気はしてたけど、約2倍ってのはなんなんだ?   gccで作った奴をVC++しかインストールしてない会社のマシンで実行しても問題なく  動作するからランタイムのせいとかでは有り得ない訳で……。 5. Completed   という訳で、SDKのCD-ROMさえあれば、VC++がなくてもWin32のアプリを作れる  環境ができましたとさ。   とはいえ、実際問題MSDN Level2の莫大なゴミ(あ、いや情報)とサンプルがないと  何もできないに等しいだろうし、グラフィカルなedittingなんて不可能ですな。   ま、趣味のプログラマでコマンドラインからの操作を好む人にとってはVC++  (BC++とかWatcomとかSymantecとか色々あるけどさ)を買わずに済むだけましかも。   ディスクスペースもより少なくて済むし。ね(^_-) #はっ!?日本語関連のライブラリとかがないぞ!!…ま、いっか 6. After care   ところがだ。VC版とgcc版のgeneric.exeの挙動が微妙に違うことに気が付いた。  クライアント領域で右クリックした時に出るメニューが違う。ソースを見ると、  その部分はWIN32シンボルが定義されてないとコンパイルされない部分だった。   故に、正しいコンパイルは:  gcc -DWIN32 -c generic.c   strip後のgeneric.exeのサイズは:14,848で多少でかくなった。とはいえ、  VC版が27,136なんでおよそ2倍という点は動かない。   そうそう。32bit consoleアプリも試してみた。putsしてるだけの奴で:  (const stringの表示にprintfを使う程あたしは間抜けではない!) #include main () { puts("test test"); }  これが全ソース。できたfoo.exeのサイズが:   gcc版:3,072、VC++ 4.0版:16,896 bytes。   実に5倍以上もの差が付いた。さすがに何かヘマをやったのではないかと疑いたく  なるけど、、、?(VCは初心者なんですよ)   蛇足。このfoo.exeと等価な動作をするプログラムをdebugで書くと: C:\> debug -a XXXX:0100 mov dx,108 XXXX:0103 mov ah,9 XXXX:0105 int 21 XXXX:0107 ret XXXX:0108 db 'test test',0d,0a,'$' XXXX:0114 -r cx CX 0000 :14 -n foo.com -w 00014 バイト書き込み中 -q C:\> foo test test C:\>   で、foo.com、しめて20 bytesてなもんだが、これは反則かしら?(笑) #…VFAT32だと1G超のHDDでも4Kクラスタだからgccとの差はない!(大穴がある反論だが)  とか(^^;; PS. 何となくだが、gccコンパイル時にWIN32の他に_WIN32も定義しておいた方が良い気がする Note: この文章は単なる.txtなんで、Alt + ←で上に戻って下さい(すっげー手抜きかも[^^;])