【C++】「デバッグ」「コンパイル」「リンク」「ビルド」

【C++】
「デバッグ」「コンパイル」「リンク」「ビルド」










「デバッグ」「コンパイル」「リンク」「ビルド」の違い


「デバッグ」と「コンパイル」「リンク」「ビルド」の違いは、 「実行テスト」と「書き出し」の違いです。


「デバッグ」と「コンパイル」「リンク」「ビルド」の違い

デバッグ「実効テスト」で、プログラムのテスト・修正が目的
コンパイル「書き出し」の一部で、完成したプログラムを実行可能なオブジェクトコードに変換する作業。
リンク「書き出し」の一部で、実行可能なオブジェクトコードのファイルを組み合わせて、実行可能な状態にする作業。
ビルド「コンパイル」と「リンク」を合わせた作業で、「コンパイル」して「リンク」することが「ビルド」。


「コンパイル」と「ビルド」は、同じように使われますが、 厳密には違います。
「コンパイル」と言うと、実行可能な形態にする「ビルド」までを意味する人もいます。
ですが、「コンパイル」をして「リンク」までして実行可能な形態にすることは「ビルド」です。
なので、「コンパイル」と「ビルド」は、同じ変換作業という意味で、同じ意味のように扱われます。

ソフト開発は、
「プログラム(デバッグ)」→「ビルド(「コンパイル」→「リンク」)」→「実行ファイルの完成」→「実行」
と言う流れになる。


Back



デバッグ


デバッグは、プログラムのバグ(誤り)を見つける作業のことで、 テストをして問題点を明らかにして、修正するため、 プログラミングにおいて、大切な作業の一つ。


デバッグをする方法




デバッグの流れ【Visual Studio 2019編】


トップメニューの「実行」

「デバッグの実行」




Back



コンパイル


「コンパイル」は、プログラムを実行可能なオブジェクトコードに変換する作業のことで、 変換作業だけなので、ファイルの関連性などは組み込まれていないので、 このままでは実行できない状態です。
コンパイルによる変換作業の後に、「ビルド(リンク)」という組み合わせ作業を経て、 「実行ファイル」となります。


コンパイラの構文【gcc編】


「gcc」を使用して、
「C++」ファイルをコンパイルするには、
「g++」コマンドを利用する。


「g++」コマンドで、コンパイルを実行する書式

g++ ファイル名.cpp -o 実行ファイル名.exe

//ソースファイルが複数ある場合
g++ ファイル名1.cpp ファイル名2.cpp -o 実行ファイル名.exe



コンパイラの構文【Visual C++編】


「コンパイル」は、ブログラムをコンピュータが実行できる形式(オブジェクトコード)に変換する作業のこと。
「コンパイル」を行うソフトウェアを「コンパイラ」と言う。
コンパイルが必要なプログラミング言語は、「コンパイラ型言語」と言う。


コンパイラの書式【Visual C++編】

cl [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...]


エントリ説明
option 1 つ以上の CL オプションを指定。
すべてのオプションは、指定されたすべてのソース ファイルに適用。
オプションは、スラッシュ (/) またはダッシュ (-) で指定。
引数を取るオプションには、オプションと引数との間にスペースを挿入する、挿入しないが別れる。
「/HELP」オプション以外のオプション名では、大文字と小文字を区別。
file 「ソース ファイル」「.obj ファイル」「ライブラリ」のいずれかの名前を指定。
「cl」は、ソース ファイルをコンパイルし、「.obj」ファイルとライブラリの名前をリンカに渡す。
lib 1 つ以上のライブラリ名を指定。
このライブラリ名はリンカに渡される。
command-file 複数のオプションをファイル名を含むファイルを指定。
link-opt 1 つ以上のリンカ オプションを指定。
指定したオプションはリンカに渡される。
「/c」オプションが指定されていないと、CL コンパイラは自動的に LINK を呼び出す。
「cl」コマンドと「オプション」「引数」でも、リンカを制御可能。


オプション / Optionの一覧

オプション目的
最適化
/O1コードを最小化。
/O2コードを最速化。
/Ob関数のインライン展開を制御。
/Od最適化を無効に。
/Ogグローバル最適化を使用。
/Oi組み込み関数を生成。
/Os実行可能ファイルで、サイズの小ささを優先させる。
/Ot実行可能ファイルで、実行速度を優先させる。
/Ox最大限の最適化 (/Ob2 ~ /Gs) を行います。
/Oyフレーム ポインタを省略します (x86 のみ)。
コード生成オプション
/archコード生成で SSE または SSE2 命令を使用(x86 のみ)。
/bigobj.obj ファイル内のアドレス指定可能なセクションの数を増や。
/clr共通言語ランタイムで実行する出力ファイルを作成。
/EH例外処理のモデルを指定。
/favor特定の x64 アーキテクチャ、または AMD64 アーキテクチャおよび Extended Memory 64 Technology (EM64T) アーキテクチャの両方のマイクロアーキテクチャの仕様に合わせて最適化されるコードを作成。
/fp浮動小数点の動作を指定。
/G1Itanium プロセッサ用に最適化。IPF クロス コンパイラまたは IPF ネイティブ コンパイラだけで使用できます。
/G2Itanium2 プロセッサ用に最適化。IPF クロス コンパイラまたは IPF ネイティブ コンパイラだけで使用できます。
/Gd__cdecl 呼び出し規約を使用(x86 のみ)。
/Geスタック プローブをアクティブに。
/GF文字列プールを有効にする。
/Ghフック関数 _penter を呼び出す。
/GHフック関数 _pexit を呼び出す。
/GLプログラム全体の最適化を有効にする。
/Gm簡易リビルドを有効にする。
/GRランタイム型情報 (RTTI: Run-Time Type Information) を有効にする。
/Gr__fastcall 呼び出し規約を使用(x86 のみ)。
/Gsスタック プローブを制御。
/GT静的スレッド ローカル ストレージを使用して割り当てられたデータに対して、ファイバ保護をサポート。
/GX同期例外処理を有効にする。
/Gy関数レベルのリンクを有効にする。
/Gz__stdcall 呼び出し規約を使用(x86 のみ)。
/MDMSVCRT.lib を使用して、マルチスレッド DLL を作成。
/MDdMSVCRTD.lib を使用して、デバッグ バージョンのマルチスレッド DLL を作成。
/MTLIBCMT.lib を使用して、マルチスレッド実行可能ファイルを作成。
/MTdLIBCMTD.lib を使用して、デバッグ バージョンのマルチスレッド実行可能ファイルを作成。
/Qfast_transcendentals高速超越関数を生成。
/Qimprecise_fwaitstry ブロックの中にある fwait コマンドを削除。
出力ファイル
/FAリスティング ファイルを作成。 リスティング ファイル名を設定。
/Faリスティング ファイルを作成。 リスティング ファイル名を設定。
/Fdプログラム データベース ファイルの名前を変更。
/Fe実行可能ファイルの名前を変更。
/Fmマップファイルを作成。
/Foオブジェクト ファイルを作成。
/Fpプリコンパイル済みヘッダー ファイルの名前を指定。
/FR/Frブラウザ ファイルを生成。
/Fx挿入されたコードをソース ファイルとマージ。
デバッグ
/GSバッファのセキュリティをチェック。
/GZ/RTC1 と同じです。
/homeparams 関数の実行に入ったときに、レジスタで渡されたパラメータを、強制的にスタック内のその場所に書き込む。
x64 コンパイラ (ネイティブ コンパイルおよびクロス コンパイル) だけで使用されるコンパイラ オプション。
/RTCランタイム エラー チェックを有効にする。
/Wp6464 ビット移植性の問題を検出。
/Ydすべてのオブジェクト ファイルに、詳細なデバッグ情報を取り込み。
/Ylデバッグ ライブラリの作成時に PCH の参照を挿入。
/Z7C 7.0 互換のデバッグ情報を生成。
/Zi詳細なデバッグ情報を生成。
/ZIエディット コンティニュと互換性のあるプログラム データベースにデバッグ情報を含めます (x86 のみ)。
/Zxデバッグ可能な最適化されたコードを生成。IPF クロス コンパイラまたは IPF ネイティブ コンパイラだけで使用できます。
プリプロセッサ
/AI#using ディレクティブに渡されたファイル参照を解決するために検索するディレクトリを指定。
/Cプリプロセス時にコメントを保持。
/D定数とマクロを定義。
/Eプリプロセッサ出力を標準出力にコピー。
/EPプリプロセッサ出力を標準出力にコピー。
/Fl指定したインクルード ファイルをプリプロセス。
/FU#using ディレクティブに渡された場合と同じ方法でファイル名の使用を強制。
/Iディレクトリ内でインクルード ファイルを検索。
/Pプリプロセッサ出力をファイルに書き込みます。
/U1 つの定義済みマクロを削除。
/uすべての定義済みマクロを削除。
/X標準のインクルード ディレクトリを無視。
言語
/openmpソース コードで #pragma omp を有効にする。
/vd隠し vtordisp クラス メンバの無効と有効を切り替え。
/vmbメンバへのポインタに対して、最適なクラスを使用。
/vmgメンバへのポインタに対して、ジェネリック クラスを使用。
/vmm多重継承を宣言。
/vms単一継承を宣言。
/vmv仮想継承を宣言。
/Za言語拡張機能を無効に。
/Zc/Ze の標準動作を指定。
/Ze言語拡張機能を有効にする。
/Zg関数プロトタイプを生成。
/Zl.obj ファイルから既定のライブラリ名を削除。
/Zpn構造体メンバをパック。
/Zs構文だけをチェック。
リンク(コンパイラで制御される LINKオプション)
/Fスタック サイズを設定。
/LD ダイナミック リンク ライブラリを作成。
/DLL を渡す。
/LDd デバッグ バージョンのダイナミック リンク ライブラリを作成。
/DLL を渡す。
/LNMSIL モジュールを作成。
/link 指定したオプションを LINK に渡す。
コマンド ラインの残りの部分を LINK に渡す。
/MD MSVCRT.lib を使用して、マルチスレッド DLL をコンパイルして作成。
「.obj 」ファイルに既定のライブラリ名を書き込む。
/MDd MSVCRTD.lib を使用して、デバッグ バージョンのマルチスレッド DLL をコンパイルして作成。
「.obj 」ファイルに既定のライブラリ名を書き込む。
シンボル _DEBUG を定義する。
/MT LIBCMT.lib を使用して、マルチスレッド実行可能ファイルをコンパイルして作成。
「.obj 」ファイルに既定のライブラリ名を書き込む。
/MTd LIBCMTD.lib を使用して、デバッグ バージョンのマルチスレッド実行可能ファイルをコンパイルして作成。
「.obj 」ファイルに既定のライブラリ名を書き込む。
シンボル _DEBUG を定義する。
拡張子 .c、.cxx、.cpp、または .def を除くすべてのファイル名LINK への入力としてファイル名を渡す。
filename.def/DEF:filename.def で渡す。
/Fnumber/STACK:number で渡す。
/Fdfilename/PDB:filename で渡す。
/Fefilename/OUT:filename で渡す。
/Fmfilename/MAP:filename で渡す。
/Gyパッケージ化された関数 (COMDAT) を作成し、関数レベルのリンクを有効にする。
/nologo/NOLOGO を渡す。
/Zd/DEBUG を渡す。
/Zi または /Z7/DEBUG を渡す。
/Zl.obj ファイルから既定のライブラリ名を省く。
プリコンパイル済みヘッダー オプション
/Y-現在のビルドで、ほかのすべてのプリコンパイル済みヘッダー コンパイラ オプションを無視。
/Ycプリコンパイル済みヘッダー ファイルを作成。
/Ydすべてのオブジェクト ファイルに、詳細なデバッグ情報を取り込み。
/Yuビルド時にプリコンパイル済みヘッダー ファイルを使用。
その他
/?コンパイラ オプションのリストを出力。
@応答ファイルを指定。
/analyzeコード分析を有効にする。
/cリンクを行わないでコンパイル。
/docドキュメト コメントを XML ファイルに出力。
/errorReport内部コンパイラ エラー (ICE) 情報を Visual C++ チームに直接提供。
/FC診断テキストで cl.exe に渡されるソース コード ファイルの完全パスを表示。
/H外部名 (パブリック名) の長さを制限。
/HELPコンパイラ オプションのリストを出力。
/hotpatchホットパッチ可能なイメージを作成。
/J既定の char 型を変更。
/MP複数のソース ファイルを同時にビルド。
/nologo著作権情報を表示しません。
QIfist浮動小数点型から整数型への変換が必要なときには、ヘルパー関数 _ftol を呼び出しません (x86 のみ)。
/QIPF_BB CPU ステップ実行のエラーに従って、予測できない結果を招く命令のシーケンスを生成しない (IPF のみ)。
/QIPF_CC CPU ステップ実行のエラーに従って、予測できない結果を招く命令のシーケンスを生成しない (IPF のみ)。
/QIPF_fr32上位の 96 ビットの浮動小数点レジスタを使用しません (IPF のみ)。
/QIPF_noPIC位置に依存するコードを持つイメージを生成します (IPF のみ)。
/QIPF_restrict_plabels実行時に関数を作成しないプログラムのパフォーマンスを向上します (IPF のみ)。
/showIncludesコンパイル時にすべてのインクルード ファイルの一覧を表示。
/Tc/TCC ソース ファイルを指定。
/Tp/TPC++ ソース ファイルを指定。
/Vバージョン文字列を設定。
/Wall既定で無効にされた警告も含めてすべての警告を有効にする。
/W警告レベルを設定。
/wすべての警告を無効に。
/WLコマンド ラインから C++ ソース コードをコンパイルするときに、エラー メッセージと警告メッセージの 1 行診断を有効にする。
/Zmプリコンパイル済みヘッダーのメモリ割り当て制限を指定。


Back



メイクファイル


「メイクファイル」は、「コンパイル」と「リンク」のコマンド指示を記述したファイルのことで、 「メイクファイル」を呼び出すだけで、「メイクファイル」に記述されたコマンド支持が実行され、 「コンパイル」と「リンク」が実行される。

「コンパイル」と「リンク」の仕方を記述したファイルが「メイクファイル」です。
決まった書式があるので、その書式通りにすれば、 「コンパイル」や「リンク」の度に、コマンドを入力しなくて済むので、 非常に便利な機能です。

「コンパイル」と「リンク」の関係性を記述したものが「メイクファイル」。


メイクファイルの保存場所


メイクファイルの保存場所は、プログラムソースと同じディレクトリ。
ファイル名は、
「Visual C++」のメイクファイル =「GNUmakefile」
「C言語」のメイクファイル = 「Makefile」
というファイル名で「メイクファイル」を作成する。



メイクファイルの書式


ターゲット名: 材料


//リンクを実行し、実行ファイル「sample」を作成
MakeEXE: sample1.o sample2.o
gcc -o Sample sample1.o sample2.o

//「sample1.c」ファイルをコンパイル
sample1: sample1.c
gcc -c sample1.c

//「sample2.c」ファイルをコンパイル
sample2: sample2.c
gcc -c sample2.c


リンクを最初に記述するのは、 材料の「sample1.o」「sample2.o」がない場合と、 過去の実行ファイルの更新日時が、材料のファイルより古い場合に、 材料の「sample1.o」「sample2.o」を再度コンパイルで作成してくれる。

後述の各ファイルのコンパイル方法を記述することで、 その関係性がわかるので、コンパイルを自動でし直してくれる。
コマンドで直に入力した場合
% gcc -c sample1.c
% gcc -c sample2.c
% gcc sample1.o sample2.o -o sample



メイクファイルでの変数の使い方


//「gcc」を変数にする
CC = gcc
//変数を使う方法
$(CC)


//変数の宣言・設定
SampleFlag = sample1.o sample2.o -o sample
DirPath = /ディレクトリ名/ファイル名
OptionText = -c /ディレクトリ名/ディレクトリ名
ObjectCodeFile = sample1.o sample2.o

//変数の呼び出し(使い方)
$(SampleFlag)
$(DirPath)
$(OptionText)
$(ObjectCodeFile)


変数名は、すべて大文字にするなどの工夫をするとわかりやすく、見やすいかもしれません。




「Makefile」を使ってのコンパイル方法


「メイクファイル」の実行方法は、「実行コマンド」を入力することで、 「メイクファイル」の内容で、「コンパイル」と「リンク」が実行される。


実行コマンド make
make ターゲット名
Visual C++の実行コマンド nmake
nmake ターゲット名




Makefile の基本的な構文


ターゲット名: 依存ファイル名 1 依存ファイル名 2 依存ファイル名 3
コマンド行 1
コマンド行 2
コマンド行 3

ターゲット名を指定して make を実行する場合
make ターゲット名



Back



リンク




Visual C++ リンカの書式

link arguments
引数[argument]で、オプションとファイル名を指定。
指定する順序は自由。
まずオプションが処理され、次にファイルが処理される。
各引数の間には 1 つ以上のスペースかタブを挿入。


link @commandfile
link /dll @objlist.txt @liblist.txt @exports.txt」
「link」へのコマンドライン引数は、コマンドファイルの形で渡すことも可能。
リンカにコマンド ファイルを指定する場合


・コマンドラインの中で、オプションは「オプション指定子 (ダッシュ (-) またはスラッシュ (/)) 」とその後ろのオプション名から構成される。
・オプション名の省略形は使用不可。
・引数を取るオプションにはコロン (:) を付け、その後ろに引数を指定。
・1 つのオプションの中には、スペースやタブを挿入不可だが、/COMMENT オプションの引用符で囲んだ文字列の中では使用可能。
・数字の引数は 10進表記か C 言語表記で指定。
・「オプション名」と「オプションのキーワードまたはファイル名の引数では、大文字と小文字が区別されないが、引数として使う識別子は大文字と小文字が区別される。

・リンカにファイルを渡す場合は、コマンド ラインで LINK コマンドの後ろにファイル名を指定。
・ファイル名は、「絶対パス」でも「相対パス」でも指定可能で、「ワイルドカード」も可能。
・ドット (.) と拡張子を省略すると、拡張子「.obj のファイル」と見なされる。
・リンカは、ファイルの実際の内容を調べて種類を判定し、それに応じて処理する。

・「cl.exe」は、動作が正常終了した場合 (エラーがない場合)、「0」を返す。エラーがある場合、リンクを停止したエラー番号を返す。
LNK1104 を生成する場合は エラー番号は「1104」。
1000=リンカがエラーについて返す最小のエラー番号 。
128=「オペレーティング システム」または「.config ファイル」の構成に問題あり。






Visual C++ リンカのオプション一覧

オプション目的
@応答ファイルを指定。
/ALIGN各セクションの配置を指定。
/ALLOWBINDDLL をバインドできないことを指定。
/ALLOWISOLATIONマニフェスト検索の動作を指定。
/ASSEMBLYDEBUG (DebuggableAttribute の追加)DebuggableAttribute をマネージ イメージに追加。
/ASSEMBLYLINKRESOURCEマネージ リソースへのリンクを作成。
/ASSEMBLYMODULEMSIL (Microsoft Intermediate Language) モジュールをアセンブリにインポートする必要があることを指定。
/ASSEMBLYRESOURCEマネージ リソース ファイルをアセンブリに埋め込みます。
/BASEプログラムのベース アドレスを設定。
/CLRIMAGETYPECLR イメージの型 (IJW、pure、または safe) を設定。
/CLRSUPPORTLASTERRORP/Invoke 機構を通じて呼び出された関数の最終エラー コードを保持。
/CLRTHREADATTRIBUTECLR プログラムのエントリ ポイントに適用するスレッド処理属性を指定。
/CLRUNMANAGEDCODECHECK/CLRUNMANAGEDCODECHECK は、マネージ コードからネイティブ DLL への呼び出しを行う、リンカによって生成された PInvoke スタブに、SuppressUnmanagedCodeSecurity 属性を適用するかどうかを指定。
/DEBUGデバッグ情報を作成。
/DEFモジュール定義 (.def) ファイルをリンカに渡。
/DEFAULTLIB外部参照を解決するときに、指定したライブラリを検索。
/DELAYDLL の遅延読み込みを制御。
/DELAYLOAD指定した DLL に遅延読み込みを発生させます。
/DELAYSIGNアセンブリに部分署名。
/DLLDLL をビルド。
/DRIVERWindows NT カーネル モード ドライバを作成。
/DYNAMICBASEWindows Vista の ASLR (Address Space Layout Randomization) 機能を使用してロード時にランダムに再ベースできる実行可能イメージを生成するかどうかを指定。
/ENTRY開始アドレスを設定。
/errorReport内部リンカ エラーを Microsoft に報告。
/EXPORT関数をエクスポート。
/FIXED指定のベース アドレスだけに読み込まれるプログラムを作成。
/FORCE未解決または複数定義のシンボルがある場合でも、リンクを強制的に終了。
/FUNCTIONPADMINホットパッチ可能なイメージを作成。
/HEAPヒープ サイズをバイト単位で設定。
/IDLOUT.idl ファイル名およびその他の MIDL の出力ファイル名を指定。
/IGNOREIDL.idl ファイル内に属性情報を挿入しません。
/IMPLIB既定のインポート ライブラリ名をオーバーライド。
/INCLUDEシンボルを明示的に参照。
/INCREMENTALインクリメンタル リンクの処理方法を制御。
/KEYCONTAINERアセンブリに署名するためのキー コンテナを指定。
/KEYFILEアセンブリに署名するためのキーまたはキー ペアを指定。
/LARGEADDRESSAWAREアプリケーションが 2 GB を超えるアドレスをサポートしていることをコンパイラに指定。
/LIBPATHユーザーが環境ライブラリ パスをオーバーライドできるように。
/LTCGリンク時コード生成を指定。
/MACHINEターゲット プラットフォームを指定。
/MANIFESTside-by-side マニフェスト ファイルを作成。
/MANIFESTDEPENDENCYマニフェスト ファイルの <dependentAssembly> セクションを指定。
/MANIFESTFILE (マニフェスト ファイルに名前を付ける)マニフェスト ファイルの既定の名前を変更。
/MANIFESTUACユーザー アカウント制御 (UAC) 情報をプログラム マニフェストに組み込むかどうかを指定。
/MAPマップファイルを作成。
/MAPINFO指定した情報をマップ ファイルに格納。
/MERGEセクションを結合。
/MIDLMIDL コマンド ライン オプションを指定。
/NOASSEMBLY.NET Framework アセンブリを作成しません。
/NODEFAULTLIB外部参照を解決するときに、すべてのまたは指定した既定のライブラリを無視。
/NOENTRYリソースだけの DLL を作成。
/NOLOGO開始メッセージを表示しません。
/NXCOMPATWindows データ実行防止機能との互換性がテスト済みとして実行可能ファイルをマーク。
/OPTLINK の最適化を制御。
/ORDER指定された順序で COMDAT をイメージに取り込みます。
/OUT出力ファイル名を指定。
/PDBプログラム データベース (PDB) ファイルを作成。
/PDBSTRIPPEDプログラム データベース (PDB) ファイルの作成時にプライベート シンボルを含めません。
/PGDガイド付き最適化のプロファイルの .pgd ファイルを指定。
/PROFILEパフォーマンス ツール プロファイラで使用できる出力ファイルを作成。
/RELEASE.exe ヘッダーにチェックサムを設定。
/SAFESEH安全な例外ハンドラのテーブルがイメージに含まれるように指定。
/SECTIONセクションの属性をオーバーライド。
/STACKスタック サイズをバイト単位で設定。
/STUBMS-DOS スタブ プログラムを Win32 プログラムにアタッチ。
/SUBSYSTEMオペレーティング システムに対して、.exe ファイルの実行方法を指定。
/SWAPRUNリンカ出力をスワップ ファイルにコピーしてから実行。
/TLBIDリンカにより生成されたタイプ ライブラリのリソース ID を指定できます。
/TLBOUT.tlb ファイル名およびその他の MIDL の出力ファイル名を指定。
/TSAWAREターミナル サーバーでの実行専用のアプリケーションを作成。
/VERBOSEリンカの進行状況メッセージを出力。
/VERSIONバージョン番号を割り当てます。
/WXリンカ警告をエラーとして扱います。


Back