Skip to content

Commit

Permalink
MSVC Build: Support VS2017 command line compiler tools
Browse files Browse the repository at this point in the history
Teach the top-level git Makefile to use whatever VS compiler
tool chain is installed on the system.

When building git from the command line in a git-sdk BASH
window with MAKE, the shell environment has environment
variables for GCC tools, but not MSVC tools.  MSVC bindings
are only avaliable from the various "VcVarsAll.bat" scripts
run by the "Developer Command Prompt" shortcuts.

Add compat/vcbuild/find_vs_env.bat to the Makefile.  It
uses the various "VcVarsAll.bat" scripts in a background
Developer Command Prompt process to compute the proper
environment variables and publish them for use by the Makefile.

[jes: fixed typos, replaced C:\WINDOWS by %SystemRoot%]

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
  • Loading branch information
jeffhostetler authored and dscho committed Aug 21, 2017
1 parent e5b6881 commit 4b21f02
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/GIT-BUILD-OPTIONS
/GIT-CFLAGS
/GIT-LDFLAGS
/GIT-MSVC-GEN
/GIT-PREFIX
/GIT-PERL-DEFINES
/GIT-PYTHON-VARS
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2715,6 +2715,7 @@ ifdef MSVC
$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(TEST_PROGRAMS))
$(RM) GIT-MSVC-GEN
endif

.PHONY: all install profile-clean clean strip
Expand Down
167 changes: 167 additions & 0 deletions compat/vcbuild/find_vs_env.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
@ECHO OFF
REM ================================================================
REM You can use either GCC (the default) or MSVC to build git
REM using the GIT-SDK command line tools.
REM $ make
REM $ make MSVC=1
REM
REM GIT-SDK BASH windows inherit environment variables with all of
REM the bin/lib/include paths for GCC. It DOES NOT inherit values
REM for the corresponding MSVC tools.
REM
REM During normal (non-git) Windows development, you launch one
REM of the provided "developer command prompts" to set environment
REM variables for the MSVC tools.
REM
REM Therefore, to allow MSVC command line builds of git from BASH
REM and MAKE, we must blend these two different worlds. This script
REM attempts to do that.
REM ================================================================
REM This BAT file starts in a plain (non-developer) command prompt,
REM searches for the "best" commmand prompt setup script, installs
REM it into the current CMD process, and exports the various MSVC
REM environment variables for use by MAKE.
REM
REM The output of this script should be written to a make "include
REM file" and referenced by the top-level Makefile.
REM
REM See "config.mak.uname" (look for GIT-MSVC-GEN).
REM ================================================================
REM The provided command prompts are custom to each VS release and
REM filled with lots of internal knowledge (such as Registry settings);
REM even their names vary by release, so it is not appropriate for us
REM to look inside them. Rather, just run them in a subordinate
REM process and extract the settings we need.
REM ================================================================
REM
REM Current (VS2017 and beyond)
REM -------------------
REM Visual Studio 2017 introduced a new installation layout and
REM support for side-by-side installation of multiple versions of
REM VS2017. Furthermore, these can all coexist with installations
REM of previous versions of VS (which have a completely different
REM layout on disk).
REM
REM VS2017 Update 2 introduced a "vswhere.exe" command:
REM https://github.com/Microsoft/vswhere
REM https://blogs.msdn.microsoft.com/heaths/2017/02/25/vswhere-available/
REM https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/
REM
REM VS2015
REM ------
REM Visual Studio 2015 uses the traditional VcVarsAll.
REM
REM Earlier Versions
REM ----------------
REM TODO
REM
REM ================================================================
REM Note: Throughout this script we use "dir <path> && <cmd>" rather
REM than "if exist <path>" because of script problems with pathnames
REM containing spaces.
REM ================================================================

REM Sanitize PATH to prevent git-sdk paths from confusing "wmic.exe"
REM (called internally in some of the system BAT files).
SET PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;

REM ================================================================

:current
SET vs_where=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
dir "%vs_where%" >nul 2>nul && GOTO have_vs_where
GOTO not_2017

:have_vs_where
REM Try to use VsWhere to get the location of VsDevCmd.

REM Keep VsDevCmd from cd'ing away.
SET VSCMD_START_DIR=.

REM Get the root of the VS product installation.
FOR /F "usebackq tokens=*" %%i IN (`"%vs_where%" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath`) DO @SET vs_ip=%%i

SET vs_devcmd=%vs_ip%\Common7\Tools\VsDevCmd.bat
dir "%vs_devcmd%" >nul 2>nul && GOTO have_vs_devcmd
GOTO not_2017

:have_vs_devcmd
REM Use VsDevCmd to setup the environment of this process.
REM Setup CL for building 64-bit apps using 64-bit tools.
@call "%vs_devcmd%" -no_logo -arch=x64 -host_arch=x64

SET tgt=%VSCMD_ARG_TGT_ARCH%

SET mn=%VCToolsInstallDir%
SET msvc_includes=-I"%mn%INCLUDE"
SET msvc_libs=-L"%mn%lib\%tgt%"
SET msvc_bin_dir=%mn%bin\Host%VSCMD_ARG_HOST_ARCH%\%tgt%

SET sdk_dir=%WindowsSdkDir%
SET sdk_ver=%WindowsSDKVersion%
SET si=%sdk_dir%Include\%sdk_ver%
SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared"
SET sl=%sdk_dir%lib\%sdk_ver%
SET sdk_libs=-L"%sl%ucrt\%tgt%" -L"%sl%um\%tgt%"

SET vs_ver=%VisualStudioVersion%

GOTO print_vars

REM ================================================================

:not_2017
REM See if VS2015 is installed.

SET vs_2015_bat=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
dir "%vs_2015_bat%" >nul 2>nul && GOTO have_vs_2015
GOTO not_2015

:have_vs_2015
REM Use VcVarsAll like the "x64 Native" command prompt.
REM Setup CL for building 64-bit apps using 64-bit tools.
@call "%vs_2015_bat%" amd64

REM Note that in VS2015 they use "x64" in some contexts and "amd64" in others.
SET mn=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\
SET msvc_includes=-I"%mn%INCLUDE"
SET msvc_libs=-L"%mn%lib\amd64"
SET msvc_bin_dir=%mn%bin\amd64

SET sdk_dir=%WindowsSdkDir%
SET sdk_ver=%WindowsSDKVersion%
SET si=%sdk_dir%Include\%sdk_ver%
SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared" -I"%si%winrt"
SET sl=%sdk_dir%lib\%sdk_ver%
SET sdk_libs=-L"%sl%ucrt\x64" -L"%sl%um\x64"

SET vs_ver=%VisualStudioVersion%

GOTO print_vars

REM ================================================================

:not_2015
REM TODO....
echo TODO support older versions of VS.
EXIT /B 1

REM ================================================================

:print_vars
REM Dump the essential vars to stdout to allow the main
REM Makefile to include it. See config.mak.uname.
REM Include DOS-style and BASH-style path for bin dir.

echo msvc_bin_dir=%msvc_bin_dir%
echo msvc_bin_dir_msys=%msvc_bin_dir:C:=/C%

echo msvc_includes=%msvc_includes%
echo msvc_libs=%msvc_libs%

echo sdk_includes=%sdk_includes%
echo sdk_libs=%sdk_libs%

echo vs_ver=%vs_ver%

EXIT /B 0
28 changes: 10 additions & 18 deletions config.mak.uname
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ ifdef MSVC
# avoid the MingW and Cygwin configuration sections
uname_S := Windows
uname_O := Windows

# Generate and include makefile variables that point to the
# currently installed set of MSVC command line tools.
GIT-MSVC-GEN: ./compat/vcbuild/find_vs_env.bat
@./compat/vcbuild/find_vs_env.bat | sed 's|\\|/|g' >GIT-MSVC-GEN
-include GIT-MSVC-GEN
endif

# We choose to avoid "if .. else if .. else .. endif endif"
Expand Down Expand Up @@ -341,7 +347,7 @@ ifeq ($(uname_S),Windows)
# link.exe next to, and required by, cl.exe, we have to prepend this
# onto the existing $PATH.
#
SANE_TOOL_PATH ?= /c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64
SANE_TOOL_PATH ?= $(msvc_bin_dir_msys)
HAVE_ALLOCA_H = YesPlease
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
Expand Down Expand Up @@ -399,26 +405,12 @@ ifeq ($(uname_S),Windows)
lib =
# Path to the unpacked third-party libraries
MSVC_DEPS = compat/vcbuild/GEN.DEPS
# Compensate for lack of %VCINSTALLDIR%, %LIB%, %LIBPATH%, and etc.
# since vcvars*.bat did not get a chance to setup the environment of
# the user's shell window.
#
# TODO If we ask the user to launch a "x64 Native" command prompt
# TODO and then have it start a git-bash window, these could be
# TODO inherited. So we wouldn't need to add these lines here.
#
MSVC_SDK81 = "c:/Program Files (x86)/Windows Kits/8.1"
MSVC_SDK10 = "c:/Program Files (x86)/Windows Kits/10"
MSVC_VCDIR = "c:/Program Files (x86)/Microsoft Visual Studio 14.0/VC"
BASIC_CFLAGS += \
-I$(MSVC_DEPS)/include -I$(MSVC_DEPS)/include/expat -I$(MSVC_DEPS)/include/zlib \
-L$(MSVC_DEPS)/lib \
-I$(MSVC_SDK81)/Include/um -I$(MSVC_SDK81)/Include/shared \
-L$(MSVC_SDK81)/lib/winv6.3/um/x64 \
-I$(MSVC_SDK10)/Include/10.0.10240.0/ucrt \
-L$(MSVC_SDK10)/lib/10.0.10240.0/ucrt/x64 \
-I$(MSVC_VCDIR)/INCLUDE \
-L$(MSVC_VCDIR)/lib/amd64
$(sdk_includes) $(sdk_libs) \
$(msvc_includes) $(msvc_libs)

# Optionally enable memory leak reporting.
# BASIC_CLFAGS += -DUSE_MSVC_CRTDBG
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
Expand Down

0 comments on commit 4b21f02

Please sign in to comment.