I use a setup similar to Casey's for my own projects, but with small differences, than make it easier to work with Vim. I always use console Vim (via Cygwin in Windows), so I don't know whether this will work for gVim.
I always edit all my source files from the project's root directory (i.e. I start vim like this: "vim code/*").
The build scripts are in the 'misc' directory and the build output goes to the 'build' directory.
The build script's (e.g. build.bat) file names are in reference to the root dir:
if not exist "build" mkdir build
cl %compiler_flags% -Fabuild\ -FAs -Fdbuild/ -Febuild/ -Fobuild/ -Fmbuild/main.map code/main.c
Note that there are no "pushd/popd build" calls and that the output is specified to be the 'build' directory explicitly.
To execute the build script I use the Dispatch Vim plugin
. In Vim: ":set makeprg=misc/build.bat". Then I call the script via ":Make" or with a custom shortcut (e.g. <leader>m) and it executes in the background. Once finished it brings the errors in the quickfix window. Without the plugin, calling ":make" will do the same, but synchronously.
To get Vim to understand the output errors from cl, I added these lines to my vimrc (MSBuild + cl.exe + fxc.exe --for HLSL):
" error message formats
" Microsoft MSBuild
set errorformat+=\\\ %#%f(%l\\\,%c):\ %m
" Microsoft compiler: cl.exe
set errorformat+=\\\ %#%f(%l)\ :\ %#%t%[A-z]%#\ %m
" Microsoft HLSL compiler: fxc.exe
set errorformat+=\\\ %#%f(%l\\\,%c-%*[0-9]):\ %#%t%[A-z]%#\ %m
I think that's all. I know this is not exactly
how Casey + Emacs do it, but it's what I've found to work best for me :)