開発者コマンドプロンプトと32bit,64bit開発環境
《 初回公開:2019/11/09 , 最終更新:2019/11/17 》
【 目次 】
64bit版のWindows10にVisual Studio 2019 Communityエディションをインストール。
VCのコンパイラcl.exeやdumpbin等のVisual Studio付属のコマンドラインツールを使うために開発者コマンドプロンプトを起動。
通常のコマンドプロンプトでVisual Studio付属のコマンドラインツールを使うにはpathの設定やらINCLUDE環境変数等の環境変数の追加設定が必要で面倒。
Developer Command Prompt for VS 2019
- Visual Studio 用開発者コマンド プロンプト | Microsoft Docs
Visual Studio 用開発者コマンド プロンプトでは、.NET Framework ツールをもっと簡単に使用できます。
それは、特定の環境変数を自動的に設定するコマンド プロンプトです。 - チュートリアル: コマンドラインでの C プログラムをコンパイルします。 | Microsoft Docs
Visual Studioをインストールした後、Windowsのスタートメニューから開発者コマンドプロンプトを探してみると、Visual Studioには他にもコマンドプロンプトのショートカットが4個存在する。
これらのコマンドプロンプトはどのように使い分けるのだろうか?
- 使用して、MicrosoftC++からコマンド ライン ツールセット | Microsoft Docs
開発者コマンド プロンプト - 32 ビット x86 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
x86 Native Tools コマンド プロンプト - 32 ビット x86 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
x64 Native Tools コマンド プロンプト - 64 ビット x64 ネイティブ ツールを使用して 64 ビット x64 ネイティブ コードをビルドするように環境を設定します。
x86_x64 Cross Tools コマンド プロンプト - 32 ビット x86 ネイティブ ツールを使用して 64 ビット x64 ネイティブ コードをビルドするように環境を設定します。
x64_x86 Cross Tools コマンド プロンプト - 64 ビット x64 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
スタートメニューのショートカットの存在するデレクトリは開発者コマンド プロンプトの場合
"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\Developer Command Prompt for VS 2019.lnk"
それ以外の4個ののショートカットの存在するデレクトリは
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC
ショートカットファイルのファイル名は
- x64 Native Tools Command Prompt for VS 2019.lnk
- x64_x86 Cross Tools Command Prompt for VS 2019.lnk
- x86 Native Tools Command Prompt for VS 2019.lnk
- x86_x64 Cross Tools Command Prompt for VS 2019.lnk
これらのVisual Studioのコマンドプロンプトについて動作確認してみた。
開発者コマンド プロンプト
- 名称
- Developer Command Prompt for VS 2019
- ショートカットファイル
- "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\Developer Command Prompt for VS 2019.lnk"
- リンク先
- %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"
- 用途
- 32 ビット x86 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
コマンドプロンプトが32bit版か64bit版かは環境変数PROCESSOR_ARCHITECTUREの値を参照する事で判定できる。
32bitで動作しているか64bitなのかの見分け方は
PROCESSOR_ARCHITECTUREの値がAMD64であれば64bit,x86であれば32bitという事になる。
一応、環境変数comspecの値も参照してみる。
********************************************************************** ** Visual Studio 2019 Developer Command Prompt v16.3.6 ** Copyright (c) 2019 Microsoft Corporation ********************************************************************** C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>echo %PROCESSOR_ARCHITECTURE% AMD64 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>echo %comspec% C:\WINDOWS\system32\cmd.exe C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>
64bit版のコマンドプロンプトとして実行されている事がわかる。
comspecの値もC:\WINDOWS\system32\cmd.exe
と64bit版のコマンドプロンプトという事になる。
参考までに32bit版コマンドプロンプトのありかはC:\Windows\SysWOW64\cmd.exe
。
- PROCESSOR_ARCHITECTUREの値
- AMD64
VC++コンパイラCL.exeの存在しているデレクトリをwhichコマンドで確認してみる。
私の環境ではunixツールのDOS版がインストールしてあるのでwhichコマンドが使えるが、もしunixツールが無い環境ではwhereコマンドでも確認できる。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>which cl.exe C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\cl.exe
- CL.exeの場所
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\cl.exe
ではCL.exeは64bitの実行プログラムなのか32bitなのかをPEヘッダーの値を参照してみる。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>dumpbin /headers "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\cl.exe" | findstr machine 14C machine (x86) 32 bit word machine
- CL.exeコンパイラ
- 32bitプログラム
CL.exeによって生成されるexeファイルが64bitなのか32bitを確認。
以下のソースをコンパイルしてみる。
このプログラムは自分自身が64bitで実行されているのか32bitで実行されているのかをコンソールに出力する。
simple.c
#include <windows.h> #include <stdio.h> void main() { BOOL bWow64; HANDLE hProc; hProc = GetCurrentProcess(); if (IsWow64Process(hProc, &bWow64)) { if (bWow64) { printf("x86\n"); } else { printf("x64\n"); } } else { printf( "IsWow64Process Failed %u\n", GetLastError()); } }
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>cd C:\HOME\test C:\HOME\test>cl simple.c Microsoft(R) C/C++ Optimizing Compiler Version 19.23.28106.4 for x86 Copyright (C) Microsoft Corporation. All rights reserved. simple.c Microsoft (R) Incremental Linker Version 14.23.28106.4 Copyright (C) Microsoft Corporation. All rights reserved. /out:simple.exe simple.obj C:\HOME\test>dumpbin /headers simple.exe | findstr machine 14C machine (x86) 32 bit word machine C:\HOME\test>simple.exe x86
- CL.exeにより生成されたexe
- 32bitプログラム
上記の結果より、開発者コマンドプロンプトは64bit版のコマンドプロンプトであり
この環境でVCコンパイラCL.exeを実行すると32bitコンパイラにより64bitのexeが生成できるのがわかる
以下、同様の手順で他のVisual Studioのコマンドプロンプトについても調べてみる。
x64 Native Tools コマンド プロンプト
- 名称
- x64 Native Tools Command Prompt for VS 2019
- ショートカットファイル
- "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC\x64 Native Tools Command Prompt for VS 2019.lnk"
- リンク先
- %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
- 用途
- 64 ビット x64 ネイティブ ツールを使用して 64 ビット x64 ネイティブ コードをビルドするように環境を設定します。
- PROCESSOR_ARCHITECTUREの値
- AMD64
- CL.exeの場所
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX64\x64\cl.exe
- CL.exeコンパイラ
- 64bitプログラム
- CL.exeにより生成されたexe
- 64bitプログラム
x64_x86 Cross Tools コマンド プロンプト
- 名称
- x64_x86 Cross Tools Command Prompt for VS 2019
- ショートカットファイル
- "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC\x64_x86 Cross Tools Command Prompt for VS 2019.lnk"
- リンク先
- %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsamd64_x86.bat"
- 用途
- 64 ビット x64 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
- PROCESSOR_ARCHITECTUREの値
- AMD64
- CL.exeの場所
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX64\x86\cl.exe
- CL.exeコンパイラ
- 64bitプログラム
- CL.exeにより生成されたexe
- 32bitプログラム
x86 Native Tools コマンド プロンプト
- 名称
- x86 Native Tools Command Prompt for VS 2019
- ショートカットファイル
- "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC\x86 Native Tools Command Prompt for VS 2019.lnk"
- リンク先
- %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars32.bat"
- 用途
- 32 ビット x86 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドするように環境を設定します。
- PROCESSOR_ARCHITECTUREの値
- AMD64
- CL.exeの場所
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\cl.exe
- CL.exeコンパイラ
- 32bitプログラム
- CL.exeにより生成されたexe
- 32bitプログラム
x86_x64 Cross Tools コマンド プロンプト
- 名称
- x86_x64 Cross Tools Command Prompt for VS 2019
- ショートカットファイル
- "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC\x86_x64 Cross Tools Command Prompt for VS 2019.lnk"
- リンク先
- %comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsx86_amd64.bat"
- 用途
- 32 ビット x86 ネイティブ ツールを使用して 64 ビット x64 ネイティブ コードをビルドするように環境を設定します。
- PROCESSOR_ARCHITECTUREの値
- AMD64
- CL.exeの場所
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x64\cl.exe
- CL.exeコンパイラ
- 32bitプログラム
- CL.exeにより生成されたexe
- 64bitプログラム
蛇足に近い考察
- Visual Studio の Cross Tools / Native Toolsって何? - 物理の駅 by onsanai
- Visual Studio (up to 2019) のコマンドラインでの C/C++ コンパイル環境 - Qiita
「開発者コマンドプロンプト」と「x86 Native Tools コマンド プロンプト」はともに「32 ビット x86 ネイティブ ツールを使用して 32 ビット x86 ネイティブ コードをビルドする」ための環境であるが、この2つの違いは開発者コマンドプロンプトが.NET Framework ツールを使う事に主眼が置かれているのに対して、他の4つのコマンド プロンプトはVC++の開発に主眼が置かれているという事のなのだろうか。
そして現時点でのデフォルトのVisual Studio付属のコマンドラインツールは「32 ビット x86 ネイティブ ツール」(開発者コマンドプロンプトの環境)という事になるのだろうか。
各コマンドプロンプトでのcl.exeの保存場所よりVisual Studio付属のコマンドラインツールの32bit版や64bit版の位置も推察できる。
- 64bit版のプログラムを開発するための64bit版のコマンドラインツール
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX64\x64\
- HostX64\x64は64bitホストPCにおいて64bit版アプリを開発するためのコマンドラインツールのデレクトリ
- 32bit版のプログラムを開発するための64bit版のコマンドラインツール
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX64\x86\
- HostX64\x86は64bitホストPCにおいて32bit版アプリを開発するためのコマンドラインツールのデレクトリ
- 32bit版のプログラムを開発するための32bit版のコマンドラインツール
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\
- HostX86\x86は32bitホストPCにおいて32bit版アプリを開発するためのコマンドラインツールのデレクトリ
- 32bit版のプログラムを開発するための64bit版のコマンドラインツール
- C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\bin\HostX86\x64\
- HostX86\x64は32bitホストPCにおいて64bit版アプリを開発するためのコマンドラインツールのデレクトリ
dumpbin等のツールもこれらのデレクトリにそれぞれのバージョンが保存されている。
「14.23.28105」の部分はMSVCのバージョンによって異なるものと思われる。
HostX64配下には64bit版WindowsOSで動作する64bit版プログラム,HostX32配下には32bit版WindowsOSで動作する32bit版プログラムが配置されているという事なのだろう。
32bit版と64bit版のコマンドプロンプトとコンソールアプリの関係
各コマンドプロンプトはすべて64bit版のコマンドプロンプトが実行されている。
では32bit版のコマンドプロンプトを起動して64bit版のコンソールアプリを実行する事はできるのだろうか。
simple.cのソースを「x64 Native Tools コマンド プロンプト」の環境でコンパイルして、32bit版のコマンドプロンプトより実行してみた。
32bit版のコマンドプロンプトを起動するにはエクスプローラを使ってC:\Windows\SysWOW64\cmd.exeを起動する事で実行できる。
32bit版のコマンドプロンプトで64bitコンソールアプリを実行してみると
C:\Windows\SysWOW64>echo %PROCESSOR_ARCHITECTURE% x86 C:\Windows\SysWOW64>C:\HOME\test\simple.exe x64
ちゃんと64bitコンソールアプリとして動作している。
これは64bit版WindowsOSの場合の話であって、32bit版WindowsOSでは当然64bitアプリは動かないだろう。
今度は、「x64 Native Tools コマンド プロンプト」より32bit版のコマンドプロンプトを常駐(/kオプションを付けてC:\Windows\SysWOW64\cmd.exeを実行)させてみる。
これにより「x64 Native Tools コマンド プロンプト」の環境変数の値を保ったまま32bit版のコマンドプロンプトを動作させる事ができ、64bitコンパイラを実行させる事もできる。
C:\HOME\test>C:\Windows\SysWOW64\cmd.exe /k C:\HOME\test>echo %PROCESSOR_ARCHITECTURE% x86 C:\HOME\test>echo cl simple.c cl simple.c C:\HOME\test>cl simple.c Microsoft(R) C/C++ Optimizing Compiler Version 19.23.28106.4 for x64 Copyright (C) Microsoft Corporation. All rights reserved. simple.c Microsoft (R) Incremental Linker Version 14.23.28106.4 Copyright (C) Microsoft Corporation. All rights reserved. /out:simple.exe simple.obj C:\HOME\test>dumpbin /headers simple.exe | findstr machine 8664 machine (x64)
面白い事に、逆に32bit版コマンドプロンプトより64bit版コマンドプロンプト(C:\Windows\System32\cmd.exe)を常駐させてみても32bit版コマンドプロンプトのままである。
C:\Windows\SysWOW64>C:\Windows\System32\cmd.exe /k C:\Windows\SysWOW64>echo %PROCESSOR_ARCHITECTURE% x86
これは、WOW64がファイルシステムをリダイレクトしているのであって、これを回避するには64ビット版コマンドプロンプトとして「%windir%\Sysnative\cmd.exe」を指定すれば良い。
C:\Windows\SysWOW64>%windir%\Sysnative\cmd.exe /k C:\Windows\SysWOW64>echo %PROCESSOR_ARCHITECTURE% AMD64
もし、64bitコマンドプロンプトから32bitコンソールアプリを起動する事ができなかった場合には
環境変数の「PROCESSOR_ARCHITECTURE」の値によって処理を変更すれば良い。
環境変数の「PROCESSOR_ARCHITECTURE」の値がx86でない場合には32bit版のコマンドラインツールを起動してその環境より32bitコンソールアプリを実行すれば良い。
if "%PROCESSOR_ARCHITECTURE%" NEQ "x86" ( C:\Windows\SysWOW64\cmd.exe /C <64bitコマンド> exit )
これらの事が何の役に立つかは別にして、「小さいことが気になる私の悪い癖」。
少しは32bit版のコマンドプロンプトにおける動作とその裏で動作しているWOW64の動作の理解にはなるかな。
nyaosで開発者コマンドプロンプト
nyaosにつては
コマンドラインを使うなら、通常のコマンドプロンプトよりnyaosの方が便利。
nyaos自体は32bitではあるが64bit1版のコンパイラ等の64bit版コンソルーアプリもnyaosで動作する。
そこで、「x64 Native Tools コマンド プロンプト」の環境を引き継いだnyaosを起動するbatファイルを作ってみた。
単純に「x64 Native Tools コマンド プロンプト」のbatファイルをcallした後にnyaosを起動してカレントディレクトリをC++のソースデレクトリに移動しているだけだが。
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" <nyaosインストール>\nyaos.exe