開発者コマンドプロンプトと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をインストールした後、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プログラム

蛇足に近い考察

「開発者コマンドプロンプト」と「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
ページのトップへ戻る