Day 001 with Visual Studio 2017

Looks like Microsoft reorganized the Visual Studio files. Here are the changes I had to make in order for the shell.bat to work correctly as on Day 001.

When installing Visual Studio 2017, choose the Desktop development with C++ option in the Workloads section. This option will install the necessary tools.

The location of vsvarsall.bat has changed in VS 2017.
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat

And the tool itself works in a slightly different manner. If you simply call vsvarsall.bat as before, when you load the command prompt you will be placed into a %somewhere%\source directory instead of W:. After digging around, I found an answer here. Either way when the command prompt opens, you will now see some output from vsvarsall.bat script reassuring you that the environment was initialized for: 'x64'.

The end result:
1
2
3
4
@echo off
set "VSCMD_START_DIR=%CD%"
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
set path=w:\handmade\misc;%path%

This is useful stuff. I remember reporting the VS 2015 issues on the Handmade Hero private github, and Casey worked them out on stream.

I think it would be useful if you also post this same information over there. Do you have access?
Casey updated to VS2017 week or two ago. His bat file now is correctly calling VS2017 env setup. This is available with latest source.

Edited by Mārtiņš Možeiko on
1
2
3
4
5
REM call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64
pushd .
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
popd
set path=w:\handmade\misc;%path%


This is the new way he does it.
Ah excellent. Casey checks the forums but probably less often than the Handmade Hero GitHub, and it's the opposite case for me so I wasn't sure.

Edited by Abner Coimbre on Reason: TYPO
I do have access to the repo although I did not know it until you mentioned it... I found the order email and clicked on the link and saw the access license key. Cool! I am happy to post the info there but it sounds like Casey has already resolved the issues.

My thought in posting the information here was for those starting at Day 001 from scratch (as I am). It would be neat if there were links on the Past Episodes pages to updated or changed info hanging out in the forums or in future episodes.
I find it easier to just set the Windows Environment path to include where vcvarsall is located. Then a simple:
1
call vcvarsall.bat x64
does the trick.
The only thing consistent with new releases of Visual Studio is Microsoft messing up paths (or methods of discovering them). Heck, the VS2015 toolset packaged with VS2017 is completely broken. Over time I've built a collection of tools and scripts to deal with all that noise.

Here's a script I use to setup the environment to use a particular version of Visual C/C++ (or Visual Studio):

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
@rem Script to find an install of particular version of Visual C/C++ and setup
@rem the environment to use it.

@rem Syntax: vc.bat [version] [sdk] [target]
@rem
@rem Options:
@rem   Versions - Version number assigned by Microsoft or `latest`.
@rem   Targets - The architecture to target. Can be `x86` or `x86_64`.
@rem   SDKs - The platform to target. Can be `windows` or `uwp`.

@echo OFF

@rem Older versions of Visual Studio can be found through the registry.

if %1%==8.0 goto find_via_registery
if %1%==9.0 goto find_via_registery
if %1%==10.0 goto find_via_registery
if %1%==11.0 goto find_via_registery
if %1%==12.0 goto find_via_registery
if %1%==14.0 goto find_via_registery

@rem Since Visual Studio 2017, however, installs can only be reliably found
@rem through COM. Instead of dealing with the many poorly documented steps
@rem required to find Visual C/C++ via COM, we use a tool maintained built by
@rem Microsoft for use.

if %1%==15.0 goto find_via_utility

@rem Passing `latest` should pick up Visual Studio 2010 or later.

if %1%==latest goto find_via_utility

echo The requested version of Visual Studio is not supported.
exit /B 1

:find_via_registery

for /F "usebackq tokens=2*" %%i in (`reg query HKLM\SOFTWARE\Microsoft\VisualStudio\%1%\Setup\VC /v "ProductDir" 2^>nul`) do (
  if not "%%j"=="" (
    set VCINSTALLDIR=%%j
    goto found_via_registery
  )
)

for /F "usebackq tokens=2*" %%i in (`reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%1%\Setup\VC /v "ProductDir" 2^>nul`) do (
  if not "%%j"=="" (
    set VCINSTALLDIR=%%j
    goto found_via_registery
  )
)

@rem We try to find a full version of Visual Studio. If we can't, then we look
@rem for standalone versions, i.e. Express Editions. This is only required for
@rem Visual Studio 2005 to 2010, so this logic can be removed when we stop
@rem supporting them.

for /F "usebackq tokens=2*" %%i in (`reg query HKLM\SOFTWARE\Microsoft\VCExpress\%1%\Setup\VC /v "ProductDir" 2^>nul`) do (
  if not "%%j"=="" (
    set VCINSTALLDIR=%%j
    goto found_via_registery
  )
)

for /F "usebackq tokens=2*" %%i in (`reg query HKLM\SOFTWARE\Wow6432Node\Microsoft\VCExpress\%1%\Setup\VC /v "ProductDir" 2^>nul`) do (
  if not "%%j"=="" (
    set VCINSTALLDIR=%%j
    goto found_via_registery
  )
)

echo Could not find Visual Studio %1% with C/C++ toolset. Is it installed?
exit /B 1

:found_via_registery

@rem Determine host architecture.
if not "%PROCESSOR_ARCHITEW6432%"=="" (
  if "%PROCESSOR_ARCHITEW6432%"=="x86" set HOST=x86
  if "%PROCESSOR_ARCHITEW6432%"=="AMD64" set HOST=amd64
) else (
  if "%PROCESSOR_ARCHITECTURE%"=="x86" set HOST=x86
  if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set HOST=amd64
)

@rem Sanity check target platform.
if not %2%==windows (
  echo Cannot target `%1%` with Visual Studio %1%.
  exit /B 1
)

@rem Map target architecture to Microsoft's monikers.
if %3%==x86 set TARGET=x86
if %3%==x86_64 set TARGET=amd64

@rem Map host and target architecutre to toolset.
if %HOST%==%TARGET% (
  set TOOLSET=%TARGET%
) else (
  set TOOLSET=%HOST%_%TARGET%
)

call "%VCINSTALLDIR%\vcvarsall.bat" %TOOLSET%

exit /B %ERRORLEVEL%

:find_via_utility

@rem Find a copy of `vswhere`, or fetch from Github if necessary.

where /Q vswhere.exe

if "%ERRORLEVEL%"=="0" (
  set VSWhere=vswhere.exe
) else (
  set VSWhere=%~dp0\tools\cache\vswhere.exe
  set VSWhereVer=2.2.7

  if not exist %~dp0\tools\cache\vswhere.exe (
    if defined DO_NOT_FETCH_TOOLS (
      echo Could not find `vswhere`!
      exit /B 1
    ) else (
      setlocal EnableDelayedExpansion

      echo Fetching vswhere@!VSWhereVer! from Github...

      mkdir %~dp0\tools 2>NUL
      mkdir %~dp0\tools\cache 2>NUL

      PowerShell.exe -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -File %~dp0\download.ps1 https://github.com/Microsoft/vswhere/releases/download/!VSWhereVer!/vswhere.exe !VSWhere!

      if not "!ERRORLEVEL!"=="0" (
        echo Failed to fetch vswhere@!VSWhereVer! from Github!
        exit /B 1
      )

      endlocal
    )
  )
)

@rem Use `vswhere` to find installation path.

for /f "usebackq tokens=*" %%t in (`%VSWhere% -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format value`) do (
  set VCINSTALLDIR=%%t
)

if not exist "%VCINSTALLDIR%\Common7\Tools\vsdevcmd.bat" (
  echo Could not find Visual Studio %1% with C/C++ toolset. Is it installed?
  exit /B 1
)

:found_via_utility

@rem Determine host architecture.
if not "%PROCESSOR_ARCHITEW6432%"=="" (
  if "%PROCESSOR_ARCHITEW6432%"=="x86" set HOST=x86
  if "%PROCESSOR_ARCHITEW6432%"=="AMD64" set HOST=amd64
) else (
  if "%PROCESSOR_ARCHITECTURE%"=="x86" set HOST=x86
  if "%PROCESSOR_ARCHITECTURE%"=="AMD64" set HOST=amd64
)

@rem Map target platform to Microsoft's monikers.
if %2%==windows set PLATFORM=Desktop
if %2%==uwp set PLATFORM=UWP

@rem Map target architecture to Microsoft's monikers.
if %3%==x86 set TARGET=x86
if %3%==x86_64 set TARGET=amd64

@rem Prevents clobbering of current working directory.
set "VSCMD_START_DIR=%CD%"

call "%VCINSTALLDIR%\Common7\Tools\vsdevcmd.bat" -no_logo -host_arch=%HOST% -arch=%TARGET% -app_platform=%PLATFORM%

exit /B %ERRORLEVEL%
Oh, yeah, almost forgot. It calls out to PowerShell to download `vswhere` if not in the PATH.

1
2
3
4
5
6
# Force errors to bubble correctly.
trap { exit 1 }

# Download the file (using WebClient to support Windows 7.)
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($args[0], $args[1])
Lol at this: https://github.com/Microsoft/vswhere
Even Microsoft themselves cannot find out where VS2017 is installed. They need separate executable for that now...