Skip to content

Find VC

Heath Stewart edited this page Dec 4, 2020 · 4 revisions

You can use vswhere.exe to find the Visual C++ compilers and linkers for different architectures. The Visual C++ team as a good blog post on different options, a couple of which are highlighted here.

The following examples use the latest release. For examples that work with older releases, please view the history of this page.

Batch

You can set up a VC build environment by calling a batch script as shown below.

@echo off

for /f "usebackq tokens=*" %%i in (`vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do (
  set InstallDir=%%i
)

if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" (
  "%InstallDir%\Common7\Tools\vsdevcmd.bat" %*
)

You could call this batch script - named vcbuild.cmd in this example - like so:

vcbuild.cmd -arch=x64 -host_arch=x64

If you want to call the VC tools directly without changing environment variables, you can read the latest version from a text file used to locate the latest toolset. For MSBuild support you can use a .props file in the same location.

@echo off
setlocal enabledelayedexpansion

for /f "usebackq tokens=*" %%i in (`vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do (
  set InstallDir=%%i
)

if exist "%InstallDir%\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" (
  set /p Version=<"%InstallDir%\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"

  rem Trim
  set Version=!Version: =!
)

if not "%Version%"=="" (
  rem Example hardcodes x64 as the host and target architecture, but you could parse it from arguments
  "%InstallDir%\VC\Tools\MSVC\%Version%\bin\HostX64\x64\cl.exe" %*
)

PowerShell

You can accomplish the tasks with PowerShell relatively easy. In the first example where the environment is set up from a script you must capture the environment variables.

$path = vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
if ($path) {
    $path = join-path $path 'Common7\Tools\vsdevcmd.bat'
    if (test-path $path) {
        cmd /s /c """$path"" $args && set" | where { $_ -match '(\w+)=(.*)' } | foreach {
            $null = new-item -force -path "Env:\$($Matches[1])" -value $Matches[2]
        }
    }
}

In contrast, the second example is straight forward and easy to add parsing of arguments.

[CmdletBinding()]
param (
  [Parameter()]
  $Arch = 'x64',

  [Parameter()]
  $HostArch = 'x64',

  [Parameter(ValueFromRemainingArguments=$true)]
  $Arguments
)

$installDir = vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
if ($installDir) {
  $path = join-path $installDir 'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt'
  if (test-path $path) {
    $version = gc -raw $path
    if ($version) {
      $version = $version.Trim()
      $path = join-path $installDir "VC\Tools\MSVC\$version\bin\Host$HostArch\$Arch\cl.exe"
      & $path $Arguments
    }
  }
}