Skip to content

Instantly share code, notes, and snippets.

@lpproj
Last active May 21, 2026 16:07
Show Gist options
  • Select an option

  • Save lpproj/fea50297ab0d837c9428a4e190b7dd0d to your computer and use it in GitHub Desktop.

Select an option

Save lpproj/fea50297ab0d837c9428a4e190b7dd0d to your computer and use it in GitHub Desktop.

gcc-ia16のWindows版をdebian 13 (trixie) で野良ビルドするための自分用メモ:
2026-01-31 lpproj
2026-02-02 lpproj
2026-02-05 lpproj
2026-02-11 lpproj

現状、いろいろ不十分。

CauseWayのDOSエクステンダを使ったバイナリをビルドする場合、内部的にシェルスクリプト(elf2dosx)を呼び出しているため、msys2のシェル上からコンパイラ(リンカ)を実行する必要がある。 (Cとかでスタンドアロン版EXEの同等品を作ればたぶん通常のWindowsコマンドプロンプト上でもいける、とは思う)

正直、Windows上でどうにかしたい場合は WSL のUbuntu内でパッケージ導入するのがたぶんいちばん楽だと思います…

ここからはじめる

https://gitlab.com/tkchia/build-ia16/

ビルドに必要なツール

  • 要するに「gcc(6.3.0)をクロスコンパイルするときに必要なツールやパッケージ」が必要になる。ただ…環境によってすでに入ってたり入ってなかったりするものが違いすぎるので、必須パッケージの完全な特定が難しい。いやほんとマジでわからん…
  • gcc/g++関連は build-essential 入れればだいたい入ると思う。
  • 本家の .gitlab-ci.yml 見るとUbuntuで必要なパッケージはだいたいわかる(が、Windows関連はビルド対象ではないので入っていない)
  • dosemuはlibi86のテストやcausewayのビルドに使うが、テストしないなら必要ない。自分は入れずに済ませる方向で対処した(ぶっちゃけ入れてもうまくビルドが進むとは限らないので…)。
  • dosboxはcausewayのビルド時に使う。
  • zip, 7zipなどは追加導入しないとダメかも。
  • dos2unixは追加導入が必要だった(causewayのビルドで使う)。
  • upxはUPX公式サイトにあるバイナリを手動でインストールして使う。apt-get経由でインストール可能なucl版はバイナリ圧縮率が劣る。(自分はupx-*-amd64-linux.tar.xzを適当な場所に展開してsudo install upx /usr/local/bin とかそんな感じでやりました…)

ビルドに必要なツール(mingw32関連)

  • apt-get install g++-mingw-w64 mingw-w64-tools
  • g++-mingw-w64 でmingw-w64方面のgcc/g++関連はだいたい全部(i686/x86_64)入ると思う。mingw-w64-tools のほうはmingw用のpkg-configが入ってるので、クロス環境向けのconfigureのことを考えると多分入れた方がいいと思う。

ビルド手順(ホスト環境)

ホスト環境(amd64 linux)用の gcc-ia16 をビルドするときは、build-ia16の README.md に書いてある順番にビルドする。 ふつうだな…!

fetch.sh

SSH→HTTPSの順番でgit cloneを試みるようになっている、けどふつうの人はHTTPSだけでいいんじゃないですかね…(というこことで自分はSSH部分をコメントアウトしてしまった)

gcc-ia16やbinutils-ia16、newlib-ia16はそのままgit cloneするとダウンロード量と時間がひどいことになるので、shallowオプションをつけたほうがいいかもしれない。

./fetch.sh gitlabs.com shallow

昔の経験だと、libi86とcausewayはリポジトリの更新が入ると update.sh 実行後のビルドがよく失敗したので、そのつど個別のリポジトリを消去してから手動で git clone --recurse-submodules し直していた。

elksはgithubにあるelks本家のほうから取ってきた方がいいかも…

causeway

ビルドが難しかった。これが作れないと libi86 がそのままビルドできない。

むかしdebian 9でビルドしていた時は少なくともソース修正の必要はなかった気がするが、13に入っているgccだとバージョンが新しすぎて古いソースのビルドに支障が出るらしい。 CFLAGSに-std=gnu90とか-std=gnu11とかつけて古めの標準にすると一応だいたい通る。

mingw関連のgccが入っていると途中でMS-DOS Playerのビルドを始めたりするので、WINCCとWINCXXを適当につぶしておく。

libi86

自分の環境だと testsuite(tests)関係でだいたい刺さって固まるので、テストしないように微妙に修正していた。

gcc-ia16

gcc本家からwaitpid関係のmingw向け修正をバックポート(Linuxホストオンリーの場合は当然不要)

ビルド手順(Windows用のクロスビルド)

基本的には公式のREADME.md通りのはずだけど、そんなにメンテナンスされてないと思われ…

そのままだといろいろ足りないので、適当に追加したり。 elf2elks-windows を追加したので、手順としては gcc2 までビルドしたあと、./mybuild.sh prereqs-windows binutils-windows elf2elks-windows gcc-windows で Windows用のコンパイラが作れる。

prereqs-windows

gccの --input-charset と --exec-charset が使いたかったので、GNU libiconvを静的リンクすることにした。 バイナリサイズがひとつ当たり 1M バイト程度増える。現在の Windows 環境なら誤差といえる。 (msys2専用でいいなら、msys2側のlibiconv.dllを使うようにすればサイズは節約できる)

あとは prefix の下からコピーしただけだとうまく入らないものを適当に prefix-windows に make install する。

binutils (binutils-windows)

gold (ld.gold.exe) が C++ やスレッドサポートを使用しており、そのままビルドすると実行時に libstdc++ や libwinpthread(や libgcc )のDLLを要求する。 msys2のシェル内から実行すればパス上にあるものを読み込んでくれないか?と思ったが、意外にそうでもない場合があるようだ…

とりあえず configure 時に LDFLAGS="-static -static-libgcc -static-libstdc++" を指定してライブラリを静的リンクすることで gold は動作するようになり、msys2 上で -mdosx のバイナリをビルドできるようになった。 (おそらく gcc-windows でも configure 時に指定しておいたほうがよいと思われる)

elks (elf2elks-windows)

コンフィグレーション (config/lxdialog):

  • 設定ツール (lxdialog) のビルドに curses が必要になる。msys2 には mingw用の cursesw パッケージが一応あるが、ヘッダとライブラリを認識させるために lxdialog 側の Makefile を修正する必要がある。
  • CFLAGS に -std=c99 が設定されているが -std=c90 にしないと途中でエラーが出た。
  • mingw-w64 には index() がない(<strings.h>は存在するが、単に<string.h>をincludeしているだけ。str[n]casecmpはstring.h側で定義されているが、[r]indexはない)ので strchr に変える。

まあlxdialogのビルドはしないで、事前に作っておいた .config を流し込んでおくのがいちばん楽だと思う(elkslibcはLinuxでビルドするので、Windows用elf2elksがビルドできるようにするだけでいい)。

elf2elks (elks/tools/elf2elks.c):

入力ファイルをオープンしたままの状態で rename や unlink を呼び出しており、Windows系ではもれなく失敗する(たぶんdjgppでビルドした DOS系でも)。 リネームや削除の前にファイルをクローズするように修正。

libelf (elks/tools/elf2elks/lib/elftoolchain-0.7.1):

  • システムヘッダ <ar.h> と <sys/queue.h> が必要。とりあえず NetBSD からヘッダを持ってくる。
  • uid_tとgid_tの定義が必要。intでいいんだろうか?(OpenWatcomだとshortになってるが…)
  • roundup, roundup2のマクロが必要。やはりBSD方面から持ってくればいいだろうか…(djgpp版のビルドではCCの指定時に -D オプションで書き足している。わりと力業)
  • ライブラリ部分がtarballになっており、make中に展開してパッチをあてている。同様の流儀でパッチを追加することになる。

r-elks.spec

これってどの段階で生成されるんだ? newlibのビルド時だろうか…

-melks 指定時は -nostdinc 状態になるせいか、gcc固有のヘッダ(<stdarg.h>とか)を読みに行ってくれない。 -isystem をむりやり追加して対処してみたが正しいやり方ではない気がする。正直よくわかっていない。

redist-windows(-tmp)

昔はあったような気がしたけど気のせいだったかもしれない…

シンプルに prefix-windows の下を固めるのを作った。Windows上だとリンクを使わない方がうれしい(≒使われるとうまく動かないことがある)ことが多いので tar -h --hard-dereference ですべて実ファイルにしてみた。

ビルド手順(djgpp用のクロスビルド)

基本的には公式のREADME.md通り…だと思う…
(causeway関係のバイナリが入ってないっぽかったので、newlib方面にむりやりねじこんでみた)

あとlibiconvは入れてない(少なくとも純正DOS環境において、1Mバイト以上のメモリ消費量増加は無視できる問題ではない)。

redist-djgpp

本家は7zipのUltraモード (-mx=9) で圧縮したzipファイルを作っている。展開には7zipが必要となる。 lzmaの展開には少なくとも辞書サイズ分のメモリが必要であり、-mx=9で圧縮したlzmaの辞書サイズは64~256Mバイトとなる。 つまり搭載メモリが64Mバイト以下の純正DOS環境でファイルの展開を行ってしまった場合、絶望的な事態を引き起こす可能性が高い。 (このことが問題になった記憶がないのだが、みんな Windows とか Linux上で展開しているのだろうか…?)

ということで辞書サイズを2Mバイトに制限するスイッチを追加した (-md=2m)。これにより出来上がるzipファイルのサイズが10%程度増加する。

@lpproj

lpproj commented Jan 31, 2026

Copy link
Copy Markdown
Author

とりあえず作ったWindows版のバイナリとパッチをOneDrive方面に置いておきました…

@lpproj

lpproj commented Feb 11, 2026

Copy link
Copy Markdown
Author

(20260211) OneDrive方面のバイナリとパッチ更新

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment