ここではコマンドラインでのビルドの方法について解説します。Visual Studioでビルドする方法については、Visual Studio での C++ プロジェクトのビルドを参照してください。
cl.exeを使用します。
CL [option...] file... [option | file]... [lib...] [@command-file] [/link link-opt...]コンパイラ コマンド ラインの構文 | MSDN
optionでコンパイラ オプションを指定します。link-optでは、リンカーに渡すリンカーオプションを指定します。
fileは、
のいずれかです。これを指定しないと「cl : コマンド ライン error D8003 : ソース ファイル名がありません」がとなります。コマンド ライン エラー D8003 (C++) | MSDN
コマンドプロンプトから直接実行した場合、「コンピュータに mspdb80.dll がないため、プログラムを開始できません。この問題を解決するには、プログラムを再インストールしてみてください。」とエラーとなることがあります。これはmspdb80.dllファイルへのパスが設定されていないためです。このファイルはMicrosoft Visual Studio x.0/Common7/IDEにあるため、このフォルダへのパスを設定すれば問題は解決されます。
Visual Studioコマンドプロンプトならば、必要な環境変数が設定されているためこのような問題は生じません。Visual Studioコマンドプロンプトは、スタートメニューから【すべてのプログラム → Microsoft Visual Studio → Visual Studio Tools → Visual Studio コマンド プロンプト】で起動できます。なお特別な名前が付いていますが、実体は必要な設定をしてコマンドプロンプトを呼び出しているにすぎません。Visual Studio コマンド プロンプト | MSDN
ところでVisual Studio 2015では、このコマンドプロンプトが対象とする環境ごとに複数用意されています。
オプションは、スラッシュ (/) またはダッシュ (–) で指定します。
/O1 スペースを最小化する /O2 スペースを最大化する /Ob<n> インライン展開 (既定値 n=0) /Od 最適化を無効にする (既定) /Og グローバルな最適化を有効にする /Oi[-] 組み込み関数を有効にする /Os コード スペースを優先する /Ot コードのスピードを優先する /Ox 最大限の最適化 /Oy[-] フレーム ポインタの省略を有効にする
/GF 読み取り専用の文字列プールを有効にする /Gm[-] 最小ビルドを有効にする /Gy[-] リンカの別の機能 /GS[-] セキュリティ チェックを有効にする /GR[-] C++ RTTI を有効にする /GX[-] C++ EH を有効にする (/EHsc と同様) /EHs C++ EH を有効にする (SEH 例外なし) /EHa C++ EH を有効にする (SEH 例外あり) /EHc extern "C" は nothrow に既定する /fp:<except[-]|fast|precise|strict> 浮動小数点モデルの選択: except[-] - コードの生成中に浮動小数点の例外を考慮します /fp:except を指定しても /Qfast_transcendentals を指定するとインライン FP 組み込みが生成されます fast - "fast" 浮動小数点モデルです。結果の予測が困難になります precise - "precise" 浮動小数点モデルです。結果は予測可能です strict - "strict" 浮動小数点モデルです (/fp:except を暗示) /GL[-] リンク時のコード生成を行う /GA Windows アプリケーション用の最適化を行う /Ge すべての関数にスタック チェックを強制する /Gs[num] スタック チェックの呼び出しを制御する /Gh _penter 関数呼び出しを有効にする /GH _pexit 関数呼び出しを有効にする /GT ファイバー セーフの TLS アクセスを生成する /RTC1 高速チェックを有効にする (/RTCsu) /RTCc 小さい型のチェックに変換する /RTCs スタック フレーム ランタイム チェック /RTCu 初期化されていないローカル変数のチェック /clr[:option] 次のオプションが指定される場合、共通言語ランタイム用にコンパイルする: pure - ネイティブな実行可能コードではなく、IL のみの出力ファイルを作成する safe - IL のみの検証可能な出力ファイルを作成する oldSyntax - Visual C++ 2002/2003 からのマネージ拡張の構文を受け入れる initialAppDomain - Visual C++ 2002 の最初の AppDomain 動作を有効にする noAssembly - アセンブリを生成しない /Gd __cdecl の呼び出し規約 /Gr __fastcall の呼び出し規約 /Gz __stdcall の呼び出し規約 /GZ スタック チェックを有効にする (/RTCs) /QIfist[-] ftol() ではなく FIST を使用する /hotpatch ホットパッチ可能なイメージのための関数パディングを確認する /arch:<SSE|SSE2> CPU アーキテクチャの最低必要条件: SSE - SSE 有効の CPU の使用法を有効にする SSE2 - SSE2 有効の CPU の使用法を有効にする /Qimprecise_fwaits は "try" 内ではなく "try" の境界上でのみ FWAIT を生成します
/arch:IA32 | 拡張命令なし |
/arch:SSE | ストリーミング SIMD 拡張命令 (SSE) |
/arch:SSE2 | ストリーミング SIMD 拡張命令 2 (SSE2) このオプションが指定されない場合の既定値 |
/arch:AVX | Advanced Vector Extensions (AVX) |
/arch:AVX2 | Advanced Vector Extensions 2 (AVX2) |
/Fa[file] アセンブリ リスト ファイル名を指定する /FA[scu] アセンブリ リストを設定する /Fd[file] .PDB ファイル名を指定する /Fe<file> .EXE ファイル名を指定する /Fm[file] マップ ファイル名を指定する /Fo<file> オブジェクト ファイル名を指定する /Fp<file> プリコンパイル済みヘッダー ファイル名を指定する /Fr[file] ソース ブラウザ ファイル名を指定する /FR[file] .SBR 拡張ファイルを指定する /doc[file] XML ドキュメント コメントを処理し、.xdc ファイルの名前を指定する
/AI<dir> アセンブリ検索パスに追加する /FU<file> アセンブリやモジュールを強制的に追加する /C コメントを削除しない /D<name>{=|#}<text> マクロを定義する /E stdout に前処理する /EP stdout に前処理する、#line なし /P ファイルを前処理する /Fx 挿入コードをファイルにマージする /FI<file> 必ず使用されるインクルード ファイル名を指定する /U<name> 定義済みのマクロを削除する /u 定義済みのマクロをすべて削除する /I<dir> インクルード検索パスに追加する /X "standard places" を無視する
/Zi デバッグ情報を有効にする /Z7 古い形式のデバッグ情報を有効にする /Zp[n] 構造体を n バイト境界でパックする /Za 拡張子を無効にする /Ze 拡張子を有効にする (既定) /Zl .OBJ で既定のライブラリ名を省略する /Zg 関数プロトタイプを生成する /Zs 構文チェックのみ /vd{0|1|2} vtordisp を無効/有効にする /vm<x> メンバへのポインタの種類 /Zc:arg1[,arg2] C++ 言語準拠です。使用できる引数: forScope[-] - スコープ ループに標準 C++ を適用する wchar_t[-] - wchar_t はネイティブ型で typedef ではない /ZI エディット コンティニュのデバッグ情報を有効にする /openmp OpenMP 2.0 言語拡張を有効にする
/LD .DLL を作成する /LDd .DLL デバッグ ライブラリを作成する /LN .netmodule を作成する /F<num> スタック サイズを設定する /link [リンカ オプションとライブラリ] /MD MSVCRT.LIB でリンクする (動的) /MT LIBCMT.LIB でリンクする (静的) /MDd MSVCRTD.LIB デバッグ ライブラリでリンクする /MTd LIBCMTd.LIB デバッグ ライブラリでリンクするcl.exe /?
オプション | バージョン | ライブラリのリンク |
---|---|---|
/MD | リリース | 動的 (Dynamic) |
/MDd | デバッグ | |
/MT ※1 | リリース | 静的 (Static) |
/MTd | デバッグ |
@<file> オプション応答ファイル /?, /help このヘルプ メッセージを出力する /bigobj 拡張オブジェクトの形式を生成する /c コンパイルのみ。リンクは行わない /errorReport:option 内部コンパイラ エラーを Microsoft に報告する none - レポートを送信しない prompt - レポートをすぐに送信するためにメッセージを表示する queue - 次の管理者ログイン時に、レポートを送信するためのメッセージを表示する (既定) send - レポートを自動的に送信する /FC 診断で完全パス名を使用する /H<num> 最大の外部名の長さ /J 文字型を既定で unsigned にする /MP[n] はコンパイル時に最大で 'n' 個のプロセスが使用されます /nologo 著作権メッセージを表示しない /showIncludes インクルード ファイル名を表示する /Tc<source file> ファイルを .c としてコンパイルする /Tp<source file> ファイルを .cpp としてコンパイルする /TC すべてのファイルを .c としてコンパイルする /TP すべてのファイルを .cpp としてコンパイルする /V<string> バージョン文字列を設定する /w 警告をすべて無効にする /wd<n> 警告 n を無効にする /we<n> 警告 n をエラーとして扱う /wo<n> 警告 n を 1 度だけ表示する /w<l><n> n の警告レベル 1-4 を設定する /W<n> 警告レベルを設定する (既定 n=1) /Wall 警告をすべて有効にする (既定で無効になっている警告も含めてすべて有効にする) /WL 1 行診断を有効にする /WX 警告をエラーとして扱う /Yc[file] .PCH ファイルを作成する /Yd デバッグ情報をすべての .OBJ に保存する /Yl[sym] デバッグ ライブラリで使用する .PCH 参照を投入する /Yu[file] .PCH ファイルを使用する /Y- PCH オプションをすべて無効にする /Zm<n> 最大メモリの割り当て (既定の %) /Wp64 64 ビット ポート警告を有効にする
オプション | 機能 |
---|---|
/w | 警告をすべて無効にする |
/W n | 警告レベルを、nに設定する |
/Wall | 既定で無効になっている警告を、すべて有効にする |
/WX | すべての警告をエラーとする |
/w ln | 警告nの警告レベルを、lとする
/w14326とすると、警告レベル1にC4326が含まれるようになる |
/wd n | 警告nを、無効にする |
/we n | 警告nを、エラーとする |
/wo n | 警告nは、1度だけ表示するようにする |
追加のセキュリティ チェック (SDL : Security Development Lifecycle / セキュリティ開発ライフサイクル) を有効化します。これによりコンパイル時にいくつかの警告がエラーと見なされるようになり、さらに実行時のエラーを防ぐためのコードが追加されます。/sdl (追加のセキュリティ チェックの有効化) | MSDN
チュートリアル: コマンド ラインでのネイティブ C++ プログラムのコンパイル (C++)を参考に、コンパイルをしてみます。
エディタ (ここではメモ帳) でファイルを作成します。
c:\>notepad basic.cpp
エディタで次のコードを記述します。
#include <iostream> int main() { std::cout << "This is a native C++ program." << std::endl; return 0; }
ファイルを保存し、エディタを閉じます。そしてコンパイラを起動し、作成したファイルをコンパイルします。
c:\>cl /EHsc basic.cpp Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. basic.cpp Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:basic.exe basic.obj
この結果、
という2つのファイルが作成されます。そして実行ファイルを実行すると、
c:\>basic This is a native C++ program.
のように、C++のプログラムが実行されたのを確認できます。
LINK [option] [file] [@command-file]リンカー コマンド ラインの構文 | MSDN
/ALIGN:# /ALLOWBIND[:NO] /ALLOWISOLATION[:NO] /ASSEMBLYDEBUG[:DISABLE] /ASSEMBLYLINKRESOURCE:ファイル名 /ASSEMBLYMODULE:ファイル名 /ASSEMBLYRESOURCE:ファイル名[,[名前][,PRIVATE]] /BASE:{アドレス[,サイズ]|@ファイル名,キー} /CLRIMAGETYPE:{IJW|PURE|SAFE} /CLRSUPPORTLASTERROR[:{NO|SYSTEMDLL}] /CLRTHREADATTRIBUTE:{STA|MTA|NONE} /CLRUNMANAGEDCODECHECK[:NO] /DEBUG /DEF:ファイル名 /DEFAULTLIB:ライブラリ /DELAY:{NOBIND|UNLOAD} /DELAYLOAD:dll /DELAYSIGN[:NO] /DLL /DRIVER[:{UPONLY|WDM}] /DYNAMICBASE[:NO] /ENTRY:シンボル /ERRORREPORT:{NONE|PROMPT|QUEUE|SEND} /EXPORT:シンボル /FIXED[:NO] /FORCE[:{MULTIPLE|UNRESOLVED}] /FUNCTIONPADMIN[:サイズ] /HEAP:予約[,コミット] /IDLOUT:ファイル名 /IGNOREIDL /IMPLIB:ファイル名 /INCLUDE:シンボル /INCREMENTAL[:NO] /KEYCONTAINER:名前 /KEYFILE:ファイル名 /LARGEADDRESSAWARE[:NO] /LIBPATH:ディレクトリ /LTCG[:{NOSTATUS|PGINSTRUMENT|PGOPTIMIZE|PGUPDATE|STATUS}] /MACHINE:{ARM|EBC|IA64|MIPS|MIPS16|MIPSFPU|MIPSFPU16| SH4|THUMB|X64|X86} /MANIFEST[:NO] /MANIFESTDEPENDENCY:マニフェスト依存関係 /MANIFESTFILE:ファイル名 /MANIFESTUAC[:{NO|UAC フラグメント}] /MAP[:ファイル名] /MAPINFO:{EXPORTS} /MERGE:マージ元の場所=マージ先の場所 /MIDL:@コマンドファイル /NOASSEMBLY /NODEFAULTLIB[:ライブラリ] /NOENTRY /NOLOGO /NXCOMPAT[:NO] /OPT:{ICF[=iterations]|NOICF|NOREF|REF} /ORDER:@ファイル名 /OUT:ファイル名 /PDB:ファイル名 /PDBSTRIPPED:ファイル名 /PGD:ファイル名 /PROFILE /RELEASE /SAFESEH[:NO] /SECTION:名前,[[!]{DEKPRSW}][,ALIGN=#] /STACK:予約[,コミット] /STUB:ファイル名 /SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION| EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER| NATIVE|POSIX|WINDOWS|WINDOWSCE}[,#[.##]] /SWAPRUN:{CD|NET} /TLBID:# /TLBOUT:ファイル名 /TSAWARE[:NO] /VERBOSE[:{ICF|LIB|REF|SAFESEH}] /VERSION:#[.#] /WX[:NO]リンカー オプション | MSDN
/DEBUG[:{FASTLINK|FULL|NONE}]-DEBUG (Generate Debug Info) | MSDN
デバッグ情報を作成できます。
FASTLINK | 高速リンク用に最適化。Visual Studio 2017以降で使用可能 |
FULL | |
NONE | PDBファイルを作成しない |
/DEF:filename/DEF (モジュール定義ファイルの指定) | MSDN
リンカーに渡す、モジュール定義ファイル (.def) を指定します。モジュール定義 (.def) ファイル | MSDN | MSDN
LTCG[:INCREMENTAL|:NOSTATUS|:STATUS|:OFF|:PGINSTRUMENT|:PGOPTIMIZE|:PGUPDATE]/LTCG (リンク時のコード生成) | MSDN
/PDB:filename/PDB (プログラム データベースの使用) | MSDN
/DEBUGオプションが指定されたときに生成されるPDBファイルを、既定の名前 (プログラムのベース名.pdb) から指定の名前に置き換えられます。/DEBUGオプションが指定されたかったときは、このオプションは無視されます。
/SAFESEH[:NO]/SAFESEH (安全な例外ハンドラーがあるイメージ) | Microsoft Learn
「/SAFESEH を指定すると、イメージの安全な例外ハンドラーのテーブルも生成できる場合に、イメージのみを生成するようにリンカーを設定します。このテーブルは、どの例外ハンドラーがイメージに対して有効であるかをオペレーティング システムに通知します。」
/VERSION:major[.minor]/VERSION (バージョン情報) | MSDN
majorとminorには0~65535の数値を指定できます。これで指定した情報は、
C:\>dumpbin /headers ファイル名
で出力される[OPTIONAL HEADER VALUES]の[image version]の項目で確認できます。
NMAKE [options] [/f makefile] [/x stderrfile] [macrodefs] [targets]NMAKE の実行 | MSDN
/fによるmakefileの指定を省略した場合は、カレントフォルダにあるMakefileファイルが使用されます。またtargetsを指定することで、 対象のファイルに記述されたラベルの位置から処理を実行させることができます。たとえばnmake clean
とすると、Makefileファイルに記述されたclean:
以下の処理から実行されます。
なお、このnmake.exeは、既定では
%COMMONPROGRAMFILES(x86)%\Microsoft Visual Studio x.0\VC\bin\nmake.exe
にインストールされています。
optionsには、以下のオプションを指定できます。
/A 評価対象をすべてビルドします /B タイム スタンプが等しい場合でもビルドします /C メッセージを出力しません /D ビルド情報を表示します /E 環境変数をメイクファイルのマクロ定義より優先します /ERRORREPORT:{NONE|PROMPT|QUEUE|SEND} エラーを Microsoft に報告します /G !include ファイル名を表示します /HELP 使い方に関する概要を表示します /I コマンドからの終了コードを無視します /K エラーが返されても、関連のない依存関係行をビルドします /N コマンドの表示だけ行い、実行はしません /NOLOGO 著作権メッセージが表示されないようにします /P NMAKE の情報を表示します /Q タイム スタンプはチェックしますがビルドは実行しません /R 前に定義された推論規則とマクロを無視します /S 実行されるコマンドを表示しません /T タイム スタンプを変更しますがビルドを実行しません /U インライン ファイルをダンプします /Y バッチモードを無効にします /? 使い方に関する概要を表示しますnmake /? NMAKE のオプション | MSDN
/Nオプションではコマンドを表示するだけで実行されないため、実行前にコマンドを確認できます。
c:\>nmake -N targets
Makefileの基本的な構文は、次の通りになります。
ターゲット1: 依存ファイル1 依存ファイル2 … コマンド1 コマンド2 … ターゲット2: 依存ファイル1 依存ファイル2 … コマンド1 … ターゲット3: コマンド1 …
このとき、
c:\>nmake ターゲット2
とするとターゲット2が実行されます。ターゲットの指定を省略すると、最初のターゲットが実行されます。上記のターゲット3のように依存ファイルの指定がない場合、つねにコマンドが実行されます。
makeでは、各コマンド行はタブから始めなければなりません。行頭がタブではないと、
Makefile:2: *** missing separator. Stop.
のようにエラーとなります。しかしnmakeではスペースも許容されます。「A command line begins with one or more spaces or tabs.」Commands in a Makefile | MSDN
行頭に「#」を置くことで、その行がコメントとみなされます。これは必ず行頭でなければならず、さもなくば
'#' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 NMAKE : fatal error U1077: '#' : リターン コード '0x1' Stop.
としてエラーとなります。
たとえば、次のような記述がされたMakefileという名前のファイルがあるとき、
all: echo Hello World
このファイルがあるフォルダで、
c:\>nmake
として実行すると、
Microsoft(R) Program Maintenance Utility Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. echo Hello World Hello World
のように出力され、最初のターゲットであるallが呼び出され、そのコマンドが実行されているのが確認できます。このとき対象がMakefileというファイル名ではないと、
NMAKE : fatal error U1064: MAKEFILE が見つかりません、またターゲットが指定されていません。 Stop.
となります。なお実行時に表示される「Microsoft(R) Program Maintenance Utility」とはnmake.exeのことですが、この著作権メッセージは/NOLOGOオプションの指定により非表示にできます。
Makefileではマクロを定義できます。その書式は、
マクロ名=値
であり、たとえば
FOO = 123 all: @echo $(FOO)
とすると、実行時に@echo $(FOO)
は@echo 123
に置換されます。
このマクロ定義はnmakeのmacrodefsオプションで上書きでき、
c:\>nmake FOO=abc
のように指定します。こうするとFOOの値はabcとなるため、結果として@echo abc
と置換されることになります。なおマクロ名では、大文字/小文字が区別されます。
64bit OS向けにビルドするには、Visual Studioのインストール フォルダのVCフォルダ (%PROGRAMFILES(x86)%\Microsoft Visual Studio x.0\VC) にあるvcvarsall.batを、対象とする環境を引数で指定して実行します。このときx86
のような形式は開発環境と実行環境が一致する場合で、x86_amd64
のような形式はそれが異なる場合に用います。
引数 | 出力されるファイル | |
---|---|---|
x86 | x86用 | 既定値 |
amd64 (またはx64) | x64用 | |
x86_amd64 | x64用 | x86マシン上ではネイティブで32ビット、64ビットマシンではWOW64により32ビット プロセスとして実行。x64 on x86 クロス |
amd64_x86 | x86用 | 64ビットマシンでネイティブのプロセスとして実行。x86 on x64 クロス |
Visual Studio 2015には、対象ごとに必要となる環境変数を設定してくれるバッチが、下表のように用意されています。
区分 | ショートカット | リンク先 |
---|---|---|
開発者コマンド プロンプト for VS2015 | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat"" | |
MSBuild | VS2015 用 MSBuild のコマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsMSBuildCmd.bat"" |
Native Tools※1 | VS2015 x86 Native Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" x86 |
VS2015 x64 Native Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64 | |
Cross Tools※1 | VS2015 x86 ARM Cross Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" x86_arm |
VS2015 x86 x64 Cross Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" x86_amd64 | |
VS2015 x64 ARM Cross Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64_arm | |
VS2015 x64 x86 Cross Tools コマンド プロンプト | %comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64_x86 |
対象のファイルをテキストエディタで開き、次の記述を検索することで判別できます。
PE L
… x86PE d・
… x64またはバイナリエディタならば、次のように表現されます。
50 45 00 00 4C 01
… x86 (0x4C = L)50 45 00 00 64 86
… x64 (0x64 = d)もしくはdumpbinのheadersオプションで出力される、[machine]の項目で確認できます。
C:\Program Files (x86)\Microsoft Visual Studio *.0\VC\bin>dumpbin.exe /headers sample.exe | findstr "machine" 14C machine (x86)
C:\Program Files (x86)\Microsoft Visual Studio *.0\VC\bin>dumpbin.exe /headers sample.exe | findstr "machine" 8664 machine (x64)How to check if a binary is 32 or 64 bit on Windows? - Super User