パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
コンパイラ

コンパイラとはプログラミング言語の処理の一種で、高水準言語のソースコードをより低水準へ変換するプログラム。

その他の外部情報

本サイトでの解釈

C++はコンパイラ言語なので、コンパイラを必要とする。コンパイラはソースコードの書かれたテキストファイルをオブジェクトファイルと呼ばれる中間生成物のバイナリファイルへコンパイル(翻訳)し、リンカと呼ばれる別プログラムが複数のオブジェクトファイルを最終の実行ファイルにリンク(合成)する。コンパイラとリンカは別プログラムでほとんどの場合それぞれを子プロセスとして呼び出す単一プログラムを通して利用するが、この単一プログラムを"コンパイラ"と呼んでしまう事が多い。本サイトもこれに従い、コンパイルのみを行う子プロセスは"狭義のコンパイラ"として区別する。

プログラミングにはデバッガと呼ばれる補助ツールが必須である。デバッガはその目的で特別にビルドされた実行ファイルを起動し、ソースコードをデバッグ(バグを検証)する。その他、デバッガほどには重要でない多くの補助ツールがある。ウィンドウズアプリケーションは"リソース"と呼ばれる読み出し専用データを実行ファイル内に埋め込む。プログラミングでこのリソースはテキストファイルとして作成され、リソースコンパイラというプログラムでバイナリファイルへ変換され、リンカでオブジェクトファイルと共にリンクされる。

覚え書き
"リソース"は別の様々な意味でも使用されるので注意されたい。以下に数例を示す。
  • コンピュータリソース(CPU占有率、メモリ容量、ハードディスク容量、ネットワーク帯域など)
  • ウィンドウズのシステムリソース(ウィンドウズオペレーティングシステムの中核が管理使用するメモリ領域)
  • wxWidgetsライブラリ利用アプリケーションを開発支援するwxSmithのリソースファイル

コンパイラ、デバッガ、リソースコンパイラ、その他の補助ツールは全てコマンドプロンプトから起動されるコマンドラインツールである。本サイトはPOSIX互換システムのMSYS2を利用してこれらを導入するが、プログラミングはより簡便な統合開発環境で行う。

本サイトはGCC(GNUのC/C++コンパイラ)のウィンドウズネイティブ版であるmingw-w64をコンパイラとして用いる。ドキュメントはGCCを参照する必要がある。準拠規格はオプション設定されるが、デフォルトはGNU拡張を加えたC++17(-std=gnu++17)である(GCC 13.2.0 Manual 2.2 C++ Language)。本サイトのサンプルコードは特に断らない限りこのデフォルトで動作確認する。

GCCドキュメント

POSIX互換システムとコンパイラ

ウィンドウズで使用できるGCCはCygwinとMinGWの二つあると説明される事が多いが、前者はPOSIX互換システムの名称で後者はコンパイラ(GCCのスペシャルバージョン)の通称である。MinGWの推奨するPOSIX互換システムはMSYSだが、MinGW自体はPOSIX互換システムに依存しない。本サイトはMSYS2とmingw-w64を使用する。MSYS2はMSYSの、mingw-w64はMinGWの改良とされるが、それぞれ全くの別物と捉えたほうが現実的である。

以降において、レイヤーDLLとはPOSIX互換システムを実現するためにプログラムとウィンドウズを仲介するダイナミックリンクライブラリ、POSIX依存コンパイラはレイヤーDLL依存のコンパイラ(自身の実行にレイヤーDLLが必要で、生成される実行ファイルもレイヤーDLLを必要とする)、ウィンドウズネイティブコンパイラはレイヤーDLLに依存しないコンパイラ(自身の実行にレイヤーDLLを必要とせず、生成される実行ファイルもレイヤーDLLを必要としない)である。

POSIX互換システム レイヤーDLL POSIX依存コンパイラ ウィンドウズネイティブコンパイラ
Cygwin cygwin1.dll GCC -
MSYS msys-1.0.dll - GCC(MinGW)
MSYS2 msys-2.0.dll GCC GCC(mingw-w64)

ウィンドウズネイティブコンパイラはPOSIX互換システムに依存しないので、表は標準的な組み合わせを示しているにすぎない。mingw-w64はCygwinでも導入できるし、SourceForge(ソフトウェアホスティングサイト)にはウィンドウズ環境で実行する単体インストーラも存在する。その理解を前提としながらも、MSYS、MSYS2はCygwinサブセットに各々のウィンドウズネイティブコンパイラを加えたものと見なせる。MSYS/MinGWは32ビットバージョンのみで古く、その役目は既にMSYS2/mingw-w64へ譲った。

mingw-w64

mingw-w64はアーキテクチャスレッドモデル、例外モデルの違いで数種類が配布されている。例えばSourceForgeのインストーラは8種類存在する。以降において、ホストはホストアーキテクチャ(コンパイラを実行するアーキテクチャ)、ターゲットはターゲットアーキテクチャ(コンパイラが生成する実行ファイルを実行するアーキテクチャ)である。両者が同一のものをネイティブコンパイラ、異なるものをクロスコンパイラと呼ぶが、以下に示すmingw-w64正規版は全てネイティブコンパイラである。

mingw-w64 ホスト ターゲット スレッドモデル 例外モデル
i686-posix-sjlj x86(32ビット) x86(32ビット) posix sjlj
i686-posix-dwarf dwarf
i686-win32-sjlj win32 sjlj
i686-win32-dwarf dwarf
x86_64-posix-sjlj x64(64ビット) x64(64ビット) posix sjlj
x86_64-posix-seh seh
x86_64-win32-sjlj win32 sjlj
x86_64-win32-seh seh

本サイトで使用するMSYS2は以下のmingw-w64をサブシステムへ導入する。

パッケージ サブシステム ホスト ターゲット スレッドモデル 例外モデル
mingw-w64-i686-gcc mingw32 x86(32ビット) x86(32ビット) posix dwarf
mingw-w64-x86_64-gcc mingw64 x64(64ビット) x64(64ビット) seh

x64(64ビット)ターゲットのGCCは32ビット実行ファイルを作成する-m32オプションを持つ。x64ターゲットmingw-w64もこのオプションで32ビットオブジェクトファイルを生成できるが、リンカが32ビット版ランタイムライブラリを発見できず実行ファイルは作成できない。mingw-w64はコンフィグに--disable-multilibを含み(g++ -vで確認できる)デフォルト以外のランタイムライブラリを持たない。そもそもウィンドウズは32ビット/64ビットで例外モデルが一般に異なるため単一の正規版mingw-w64による両対応は不可能と考えるべきである。

tdm-gcc

tdm-gccは本サイトで使用しないが、MinGWあるいはmingw-w64の非正規版の一つである。単独インストーラで供給されウィンドウズへの導入はMSYS2より簡便である一方、boostやwxWidgetsといった標準以外のライブラリ追加を自力で行う必要がある。MinGWベースのTDM32とmingw-w64ベースのTDM64がある。

tdm-gcc ベース オプション ホスト ターゲット スレッドモデル 例外モデル
TDM32 MinGW n/a x86(32ビット) x86(32ビット) posix sjlj
TDM32(DW2) dwarf
TDM64 mingw-w64 -m32 x86(32ビット) x86(32ビット) posix sjlj
-m64(デフォルト) x64(64ビット) seh

TDM64はx86(32ビット)ホストでx86(32ビット)とx64(64ビット)の複数をターゲットとする。デフォルトはx64ターゲットで狭義にはクロスコンパイラと考えられるが、恐らくx64ホストシステム(のx86互換機能)でx64ターゲットを作成するとして自らをネイティブコンパイラと定義している。-m32/-m64オプションで例外モデルを切り替える独自機能を実装しmultilibを有効としている。2015年以降長らく活動が見られなかったが、2020年ひさびさにアップデートされた。