|
本サイトは移転しました。旧アドレスからのリダイレクトは2025年03月31日(月)まで有効です。
|
🛈 | ✖ |
コンパイラとはプログラミング言語の処理の一種で、高水準言語のソースコードをより低水準へ変換するプログラム。
C++はコンパイラ言語なので、コンパイラを必要とする。コンパイラはソースコードの書かれたテキストファイルをオブジェクトファイルと呼ばれる中間生成物のバイナリファイルへコンパイル(翻訳)し、リンカと呼ばれる別プログラムが複数のオブジェクトファイルを最終の実行ファイルにリンク(合成)する。コンパイラとリンカは別プログラムでほとんどの場合それぞれを子プロセスとして呼び出す単一プログラムを通して利用するが、この単一プログラムを"コンパイラ"と呼んでしまう事が多い。本サイトもこれに従い、コンパイルのみを行う子プロセスは"狭義のコンパイラ"として区別する。
プログラミングにはデバッガと呼ばれる補助ツールが必須である。デバッガはその目的で特別にビルドされた実行ファイルを起動し、ソースコードをデバッグ(バグを検証)する。その他、デバッガほどには重要でない多くの補助ツールがある。ウィンドウズアプリケーションは"リソース"と呼ばれる読み出し専用データを実行ファイル内に埋め込む。プログラミングでこのリソースはテキストファイルとして作成され、リソースコンパイラというプログラムでバイナリファイルへ変換され、リンカでオブジェクトファイルと共にリンクされる。
コンパイラ、デバッガ、リソースコンパイラ、その他の補助ツールは全てコマンドプロンプトから起動されるコマンドラインツールである。本サイトはPOSIX互換システムのMSYS2を利用してこれらを導入するが、プログラミングはより簡便な統合開発環境で行う。
本サイトはGCC(GNUのC/C++コンパイラ)のウィンドウズネイティブ版であるmingw-w64をコンパイラとして用いる。ドキュメントはGCCを参照する必要がある。準拠規格はオプション設定されるが、デフォルトはGNU拡張を加えたC++17(-std=gnu++17)である(GCC 14.1.0 Manual 2.2 C++ Language)。本サイトのサンプルコードは特に断らない限りこのデフォルトで動作確認する。
ウィンドウズで使用できる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はアーキテクチャ、スレッドモデル、例外モデルの違いで数種類が配布されている。例えば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は本サイトで使用しないが、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年ひさびさにアップデートされた。