🐯

build-gcc で djgpp をビルドする

に公開

32bit dos 向け exe を生成できる djgpp のクロスコンパイルとして、以前build-djgpp というモノを使ってみたけれど、その派生に build-gcc というのがある模様。

build-gcc は、クロスコンパイラ環境作成に必要な gcc やツールやパッチやらをダウンロードしてビルドしてインストールが行える代物で、djgpp のビルドだけでなく gcc-ia16-elf、AVR 用 gcc も同様な手順でビルドが行えるらしい。

windows としては msys2 環境を使う。

djgpp で gcc/g++ 14.x が使え、コンパイラは i386 用になっている。(設定変更で i586 可)
古い PC98 系向けにコンパイルしたい向きとしては嬉しい。

が、ちと残念なことに、バイナリ配布はなさそうなので、自分でビルドする必要あり。

ということで、そのメモ。

前準備 (msys2)

build-gcc は build-djgpp 同様、win(mingw系)、mac,linux 等で動くクロスコンパイラを生成できるけど、今回試すのは win64。

msys2 がなければ、まずはそれを windows にインストール。
msys2 のインストールについてはググるなり chat ai に聞くなりなんなりで。

どこでもいいけど、ここではデフォルトの c:\msys64 にインストールしたものとしておく。

ビルドをする環境としては、mingw64 を使用。

mingw64.exe を実行した環境にて、build-gcc のREADME に書いてあるまま、

$ pacman -Syuu base-devel mingw-w64-x86_64-{toolchain,curl,zlib,python3} compression m4 dos2unix nasm

で、gccのビルドに必要なツール群をインストール。

msys2 には、他にも ucrt64 とか、clang64 とか複数の実行環境があるけど、今回は mingw64。
最初に ucrt64 でビルド試してこけて mingw64 では通ったから他は未検証。
ucrt64 のほうが今どきの windows 用プログラム向だけど、unix/linux との互換性的には mingw64 のほうがよさそうなのかも、と。

ビルド&使用

build-gcc を適当なところに clone する。
ここでは、x:\build-gcc で作業し、お好みの git クライアントで clone。コマンドラインだと

git clone https://github.com/jwt27/build-gcc.git

mingw64.exe 環境で、clone したフォルダに移動。

cd /x/build-gcc

とりあえず djgpp 2.05 の gcc14.2 を、msys2 環境(c:/msys64/) の usr/local/MinGW64/djgpp2.05-gcc14.2 にインストールするとして、

export CFLAGS="-std=gnu11"
export CXXFLAGS="-std=gnu++11"
./build-djgpp.sh --prefix=/usr/local/MinGW64/djgpp2.05-gcc14.2 binutils-2.39 djgpp-2.05 gcc-14.2.0

とすれば、時間はかかるけれど、指定フォルダにクロスコンパイラ一式できるはず。

インストール先パスはお好みで。できたフォルダを c:\djgpp とかにコピーするでも。

できた gcc/g++ を、(msys 環境でなく) windows プロンプトで使う場合は、

set "MSYS2_DIR=c:\msys64"
set "DJGPP_DIR=%MSYS2_DIR%\usr\local\MinGW64\djgpp2.05-gcc14.2"
set "PATH=%DJGPP_DIR%\bin;%MSYS_DIR%\mingw32\bin;%MSYS_DIR%\usr\bin;%PATH%"
set "PATH=%DJGPP_DIR%\i386-pc-msdosdjgpp\bin;%PATH%"
set "GCC_EXEC_PREFIX=%DJGPP_DIR%\lib\gcc\"

みたいな感じにパスを通して使っている。

他のバージョンのビルド等

できてしまえば簡単だけど。いろいろハマった。

まず msys2 環境の gcc のバージョンが上がり過ぎていて(現在 gcc/g++ 15.x)、デフォルトが c++23 だったりするので、以前なら警告ですんでいたモノがエラーになったりするため、コンパイルが通る言語バージョンの指定が必須。

それとビルドする djgpp,gcc,binutils のバージョンの選択。
(クロスコンパイラということもあり面倒もあり gdb は無し)

./build-djgpp.sh のみを実行すると、引数説明と、指定可能な、gcc、binutils、gdb、djgpp のバージョン込の選択肢が表示されるが、当然ながらその全ての組み合わせができるでなく。

というか、そもそも一覧にはビルドできないバージョンも混じっていて、通るバージョンを見つける必要あり。
build-gcc は djgpp だけでなく AVR 用gcc ビルドもあるので、その対応物のバージョンも混じっていそうで、djgpp側パッチがなかったりする。
もちろん all や バージョン無しの指定は最新バージョンが使われるみたいで不適。

試した範囲では、gcc9,10,12,14 はビルドできたが、gcc8 以前は今のところ成功せず。

今回は以下のように選択。

djgpp は djgpp-2.05 と djgpp-cvs の2択だけれど、とりあえず安定版ぽい2.05を使用。

言語バージョンは c11,c++11 で、 gcc 9.x ~ gcc 14.x はビルド可能。
※ gcc 11 以降は c++17 が公式デフォぽいのでそちらのほうがよかったかも。

gnu 拡張は使うので、環境変数の設定は

export CFLAGS="-std=gnu11"
export CXXFLAGS="-std=gnu++11"

gcc と binutils のバージョンは、こちらで試した結果は

gcc ver. binutils ver.
9.2.0 2.33.1
10.2.0 2.33.1
12.1.0 2.39
14.2.0 2.39

djgpp で対応している gcc のみなので、11,13系はなし。

build-djgpp で設定される gcc-8.3.0 ~ 12.2 の binutils は 2.30 固定だったので、それ以降の非互換が発生しない版なら通りそう。で 2.34 とか 2.40 あたりに境目があるぽいので、それは避けて gcc のバージョンに近いものを採用。
※ ただ build-djgpp での実績を思うなら、悩まず 2.30 でよかったかも。

おわりに

gcc にしろ binutils にしろ細かいバージョン指定、通ったり通らなかったり。

build-djgpp ではビルド可能だった gcc 9.3.0、10.3.0、12.2.0 がビルドできないし。が、エラーにみてると当然と思えたり、むしろ build-djgpp が何かがんばってる?
build-gcc は build-djgpp とは、使い方が別物で、コマンドラインで組み合わせ選択するけれど、build-djgpp はバージョン決め打ちでそのぶん細かいことやってたのかな、と。

あと、build-gcc に含まれる gcc-ia16-elf のほうだけど、こちらは上手くビルドできず。
ただ、gcc-ia16-elf 公式の ubuntu 22.04 版にはあるソース非公開の dos 用ライブラリが含まれていないので、結局使うなら公式版、てことになりそうで、深く追求せず。
(AVR 関係はモノもってないので試さず)

古い gcc 用の msys2 環境をつくれば、試せる可能性あるけれど、それはそれで面倒そう…

[追記] PC98用にする手順を こちら に書いた。

Discussion