1#!/bin/bash
2# This configures the environment for running MSVC.  It uses vswhere, the
3# registry, and a little knowledge of how MSVC is laid out.
4
5if ! hash vswhere 2>/dev/null; then
6    echo "Can't find vswhere on the path, aborting" 1>&2
7    exit 1
8fi
9
10if ! hash reg 2>/dev/null; then
11    echo "Can't find reg on the path, aborting" 1>&2
12    exit 1
13fi
14
15# Turn a unix-y path into a windows one.
16fixpath() {
17    if hash cygpath 2>/dev/null; then
18        cygpath --unix "$1"
19    else # haxx
20        echo "$1" | sed -e 's,\\,/,g;s,^\(.\):,/\L\1,;s,/$,,'
21    fi
22}
23
24# Query the registry.  This takes $1 and tags that on the end of several
25# different paths, looking for a value called $2 at that location.
26# e.g.,
27#   regquery Microsoft\Microsoft SDKs\Windows\v10.0 ProductVersion
28# looks for a REG_SZ value called ProductVersion at
29#   HKLM\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
30#   HKLU\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
31#   etc...
32regquery() {
33    search=("HKLM\\SOFTWARE\\Wow6432Node" \
34            "HKCU\\SOFTWARE\\Wow6432Node" \
35            "HKLM\\SOFTWARE" \
36            "HKCU\\SOFTWARE")
37    for i in "${search[@]}"; do
38        r=$(reg query "${i}\\${1}" -v "$2" | sed -e 's/ *'"$2"' *REG_SZ *//;t;d')
39        if [ -n "$r" ]; then
40            echo "$r"
41            return 0
42        fi
43    done
44    return 1
45}
46
47VSCOMPONENT=Microsoft.VisualStudio.Component.VC.Tools.x86.x64
48vsinstall=$(vswhere -latest -requires "$VSCOMPONENT" -property installationPath)
49
50# Attempt to setup paths if vswhere returns something and VSPATH isn't set.
51# Otherwise, assume that the env is setup.
52if [[ -n "$vsinstall" && -z "$VSPATH" ]]; then
53
54    case "$target_arch" in
55        ia32) m=x86 ;;
56        x64) m="$target_arch" ;;
57        *)
58            echo "No support for target '$target_arch' with MSVC." 1>&2
59            exit 1
60    esac
61
62    export VSPATH=$(fixpath "$vsinstall")
63    export WINDOWSSDKDIR="${VSPATH}/SDK"
64    export VCINSTALLDIR="${VSPATH}/VC"
65
66    CRTREG="Microsoft\\Microsoft SDKs\\Windows\\v10.0"
67    UniversalCRTSdkDir=$(regquery "$CRTREG" InstallationFolder)
68    UniversalCRTSdkDir=$(fixpath "$UniversalCRTSdkDir")
69    UCRTVersion=$(regquery "$CRTREG" ProductVersion)
70    UCRTVersion=$(cd "${UniversalCRTSdkDir}/include"; ls -d "${UCRTVersion}"* | tail -1)
71
72    VCVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt")
73    REDISTVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCRedistVersion.default.txt")
74    export WIN32_REDIST_DIR="${VCINSTALLDIR}/Redist/MSVC/${REDISTVER}/${m}/Microsoft.VC141.CRT"
75    export WIN_UCRT_REDIST_DIR="${UniversalCRTSdkDir}/Redist/ucrt/DLLs/${m}"
76
77    if [ "$m" == "x86" ]; then
78        PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Hostx64/x64"
79        PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Hostx64/x86"
80    fi
81    PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Host${m}/${m}"
82    PATH="${PATH}:${UniversalCRTSdkDir}/bin/${UCRTVersion}/${m}"
83    PATH="${PATH}:${WIN32_REDIST_DIR}"
84    export PATH
85
86    INCLUDE="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/ATLMFC/include"
87    INCLUDE="${INCLUDE}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/include"
88    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/ucrt"
89    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/shared"
90    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/um"
91    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/winrt"
92    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/cppwinrt"
93    export INCLUDE
94
95    LIB="${VCINSTALLDIR}/lib/${m}"
96    LIB="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/lib/${m}"
97    LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/ucrt/${m}"
98    LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/um/${m}"
99    export LIB
100
101    export GYP_MSVS_OVERRIDE_PATH="${VSPATH}"
102    export GYP_MSVS_VERSION=$(vswhere -latest -requires "$VSCOMPONENT" -property catalog_productLineVersion)
103else
104    echo Assuming env setup is already done.
105    echo VSPATH=$VSPATH
106fi
107