Skip to content

Commit

Permalink
Bug 1434943 - Support for MSVC in build.sh, r=jcj
Browse files Browse the repository at this point in the history
This adds basic support for MSVC to build.sh.  It uses the registry and vswhere
(which is part of the standard mozilla-build setup now) to work out paths and
set them properly.  It's probably a little fragile, but it's better than the
shoestring and tape we have in builds right now.

I took the liberty of sanitizing the command-line options a little here.  Mostly
that is sorting them, but I also deprecated the -m32 option in favour of
specifying target architecture with -t.  That turned out to be a lot cleaner.

--HG--
extra : rebase_source : 5f62c7a277de0c13f7a2c0ac1e495095dc803841
extra : amend_source : e6db2463ea560ada42ca091023e87adce284a853
  • Loading branch information
martinthomson committed Jun 1, 2018
1 parent efd8876 commit 762709e
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 86 deletions.
14 changes: 7 additions & 7 deletions automation/taskcluster/graph/src/extend.js
Expand Up @@ -152,13 +152,13 @@ export default async function main() {
await scheduleLinux("Linux 32 (opt)", {
platform: "linux32",
image: LINUX_IMAGE
}, "-m32 --opt");
}, "-t ia32 --opt");

await scheduleLinux("Linux 32 (debug)", {
platform: "linux32",
collection: "debug",
image: LINUX_IMAGE
}, "-m32");
}, "-t ia32");

await scheduleLinux("Linux 64 (opt)", {
platform: "linux64",
Expand Down Expand Up @@ -248,12 +248,12 @@ export default async function main() {

await scheduleWindows("Windows 2012 32 (opt)", {
platform: "windows2012-32",
}, "build_gyp.sh --opt -m32");
}, "build_gyp.sh --opt -t ia32");

await scheduleWindows("Windows 2012 32 (debug)", {
platform: "windows2012-32",
collection: "debug"
}, "build_gyp.sh -m32");
}, "build_gyp.sh -t ia32");

await scheduleFuzzing();
await scheduleFuzzing32();
Expand Down Expand Up @@ -679,7 +679,7 @@ async function scheduleFuzzing32() {
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz -m32"
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz -t ia32"
],
artifacts: {
public: {
Expand All @@ -706,7 +706,7 @@ async function scheduleFuzzing32() {
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls -m32"
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls -t ia32"
],
}));

Expand Down Expand Up @@ -1102,7 +1102,7 @@ async function scheduleTools() {
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --disable-tests --emit-llvm -m32"
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --disable-tests --emit-llvm -t ia32"
]
}));

Expand Down
101 changes: 54 additions & 47 deletions build.sh
Expand Up @@ -50,75 +50,85 @@ fuzz=0
fuzz_tls=0
fuzz_oss=0
no_local_nspr=0
armhf=0

gyp_params=(--depth="$cwd" --generator-output=".")
nspr_params=()
ninja_params=()

# try to guess sensible defaults
arch=$(python "$cwd"/coreconf/detect_host_arch.py)
if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
build_64=1
elif [ "$arch" = "arm" ]; then
armhf=1
# Assume that the target architecture is the same as the host by default.
host_arch=$(python "$cwd"/coreconf/detect_host_arch.py)
target_arch=$host_arch

# Assume that MSVC is wanted if this is running on windows.
platform=$(uname -s)
if [ "${platform%-*}" = "MINGW32_NT" -o "${platform%-*}" = "MINGW64_NT" ]; then
msvc=1
fi

# parse command line arguments
# Parse command line arguments.
while [ $# -gt 0 ]; do
case $1 in
case "$1" in
-c) clean=1 ;;
-cc) clean_only=1 ;;
--gyp|-g) rebuild_gyp=1 ;;
--nspr) nspr_clean; rebuild_nspr=1 ;;
-j) ninja_params+=(-j "$2"); shift ;;
-v) ninja_params+=(-v); verbose=1 ;;
--test) gyp_params+=(-Dtest_build=1) ;;
--clang) export CC=clang; export CCC=clang++; export CXX=clang++ ;;
--gcc) export CC=gcc; export CCC=g++; export CXX=g++ ;;
--fuzz) fuzz=1 ;;
--fuzz=oss) fuzz=1; fuzz_oss=1 ;;
--fuzz=tls) fuzz=1; fuzz_tls=1 ;;
-j) ninja_params+=(-j "$2"); shift ;;
--gyp|-g) rebuild_gyp=1 ;;
--opt|-o) opt_build=1 ;;
-m32|--m32) target_arch=ia32; echo 'Warning: use -t instead of -m32' 1>&2 ;;
-t|--target) target_arch="$2"; shift ;;
--target=*) target_arch="${1#*=}" ;;
--clang) export CC=clang; export CCC=clang++; export CXX=clang++; msvc=0 ;;
--gcc) export CC=gcc; export CCC=g++; export CXX=g++; msvc=0 ;;
--msvc) msvc=1 ;;
--scan-build) enable_scanbuild ;;
--scan-build=?*) enable_scanbuild "${1#*=}" ;;
--opt|-o) opt_build=1 ;;
-m32|--m32) build_64=0 ;;
--disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
--pprof) gyp_params+=(-Duse_pprof=1) ;;
--asan) enable_sanitizer asan ;;
--msan) enable_sanitizer msan ;;
--ubsan) enable_ubsan ;;
--ubsan=?*) enable_ubsan "${1#*=}" ;;
--fuzz) fuzz=1 ;;
--fuzz=oss) fuzz=1; fuzz_oss=1 ;;
--fuzz=tls) fuzz=1; fuzz_tls=1 ;;
--sancov) enable_sancov ;;
--sancov=?*) enable_sancov "${1#*=}" ;;
--pprof) gyp_params+=(-Duse_pprof=1) ;;
--ct-verif) gyp_params+=(-Dct_verif=1) ;;
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
--disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
--no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
--system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
--test) gyp_params+=(-Dtest_build=1) ;;
--ct-verif) gyp_params+=(-Dct_verif=1) ;;
--nspr) nspr_clean; rebuild_nspr=1 ;;
--with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;;
--system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;;
--enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
--system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
--enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
--enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
*) show_help; exit 2 ;;
esac
shift
done

# Set the target architecture and build type.
gyp_params+=(-Dtarget_arch="$target_arch")
if [ "$opt_build" = 1 ]; then
target=Release
else
target=Debug
fi
if [ "$build_64" = 1 ]; then
nspr_params+=(--enable-64bit)
elif [ ! "$armhf" = 1 ]; then
gyp_params+=(-Dtarget_arch=ia32)
fi

# Do special setup.
if [ "$fuzz" = 1 ]; then
source "$cwd"/coreconf/fuzz.sh
fi
nspr_set_flags $sanitizer_flags
if [ ! -z "$sanitizer_flags" ]; then
gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
fi

# set paths
if [ "$msvc" = 1 ]; then
source "$cwd"/coreconf/msvc.sh
fi

# Setup build paths.
target_dir="$cwd"/out/$target
mkdir -p "$target_dir"
dist_dir="$cwd"/../dist
Expand Down Expand Up @@ -149,6 +159,7 @@ check_config()
echo CC="$CC" >"$newconf"
echo CCC="$CCC" >>"$newconf"
echo CXX="$CXX" >>"$newconf"
echo target_arch="$target_arch" >>"$newconf"
for i in "$@"; do echo $i; done | sort >>"$newconf"

# Note: The following diff fails if $oldconf isn't there as well, which
Expand All @@ -159,6 +170,7 @@ check_config()
gyp_config="$cwd"/out/gyp_config
nspr_config="$cwd"/out/$target/nspr_config

# Now check what needs to be rebuilt.
# If we don't have a build directory make sure that we rebuild.
if [ ! -d "$target_dir" ]; then
rebuild_nspr=1
Expand All @@ -167,33 +179,28 @@ elif [ ! -d "$dist_dir"/$target ]; then
rebuild_nspr=1
fi

# Update NSPR ${C,CXX,LD}FLAGS.
nspr_set_flags $sanitizer_flags

if check_config "$nspr_config" "${nspr_params[@]}" \
if check_config "$nspr_config" \
nspr_cflags="$nspr_cflags" \
nspr_cxxflags="$nspr_cxxflags" \
nspr_ldflags="$nspr_ldflags"; then
rebuild_nspr=1
fi

# Forward sanitizer flags.
if [ ! -z "$sanitizer_flags" ]; then
gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
fi

if check_config "$gyp_config" "${gyp_params[@]}"; then
rebuild_gyp=1
fi

# save the chosen target
# Save the chosen target.
mkdir -p "$dist_dir"
echo $target > "$dist_dir"/latest

# Build.
# NSPR.
if [[ "$rebuild_nspr" = 1 && "$no_local_nspr" = 0 ]]; then
nspr_build "${nspr_params[@]}"
nspr_build
mv -f "$nspr_config".new "$nspr_config"
fi
# gyp.
if [ "$rebuild_gyp" = 1 ]; then
if ! hash ${GYP} 2> /dev/null; then
echo "Please install gyp" 1>&2
Expand All @@ -211,11 +218,11 @@ if [ "$rebuild_gyp" = 1 ]; then
mv -f "$gyp_config".new "$gyp_config"
fi

# Run ninja.
if hash ninja 2>/dev/null; then
ninja=ninja
elif hash ninja-build 2>/dev/null; then
# ninja.
if hash ninja-build 2>/dev/null; then
ninja=ninja-build
elif hash ninja 2>/dev/null; then
ninja=ninja
else
echo "Please install ninja" 1>&2
exit 1
Expand Down
7 changes: 3 additions & 4 deletions coreconf/fuzz.sh
Expand Up @@ -5,8 +5,7 @@ set +e

# Default to clang if CC is not set.
if [ -z "$CC" ]; then
command -v clang &> /dev/null 2>&1
if [ $? != 0 ]; then
if ! command -v clang &> /dev/null 2>&1; then
echo "Fuzzing requires clang!"
exit 1
fi
Expand All @@ -24,8 +23,8 @@ if [ "$fuzz_oss" = 1 ]; then
gyp_params+=(-Dno_zdefs=1 -Dfuzz_oss=1)
else
enable_sanitizer asan
# Ubsan doesn't build on 32-bit at the moment. Disable it.
if [ "$build_64" = 1 ]; then
# Ubsan only builds on x64 for the moment.
if [ "$target_arch" = "x64" ]; then
enable_ubsan
fi
enable_sancov
Expand Down
98 changes: 98 additions & 0 deletions coreconf/msvc.sh
@@ -0,0 +1,98 @@
#!/bin/bash
# This configures the environment for running MSVC. It uses vswhere, the
# registry, and a little knowledge of how MSVC is laid out.

if ! hash vswhere 2>/dev/null; then
echo "Can't find vswhere on the path, aborting" 1>&2
exit 1
fi

if ! hash reg 2>/dev/null; then
echo "Can't find reg on the path, aborting" 1>&2
exit 1
fi

# Turn a unix-y path into a windows one.
fixpath() {
if hash cygpath 2>/dev/null; then
cygpath --unix "$1"
else # haxx
echo "$1" | sed -e 's,\\,/,g;s,^\(.\):,/\L\1,;s,/$,,'
fi
}

# Query the registry. This takes $1 and tags that on the end of several
# different paths, looking for a value called $2 at that location.
# e.g.,
# regquery Microsoft\Microsoft SDKs\Windows\v10.0 ProductVersion
# looks for a REG_SZ value called ProductVersion at
# HKLM\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
# HKLU\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
# etc...
regquery() {
search=("HKLM\\SOFTWARE\\Wow6432Node" \
"HKCU\\SOFTWARE\\Wow6432Node" \
"HKLM\\SOFTWARE" \
"HKCU\\SOFTWARE")
for i in "${search[@]}"; do
r=$(reg query "${i}\\${1}" -v "$2" | sed -e 's/ *'"$2"' *REG_SZ *//;t;d')
if [ -n "$r" ]; then
echo "$r"
return 0
fi
done
return 1
}

case "$target_arch" in
ia32) m=x86 ;;
x64) m="$target_arch" ;;
*)
echo "No support for target architecture '$target_arch' with MSVC." 1>&2
exit 1
esac

VSCOMPONENT=Microsoft.VisualStudio.Component.VC.Tools.x86.x64
VSPATH=$(vswhere -latest -requires "$VSCOMPONENT" -property installationPath)
export VSPATH=$(fixpath "$VSPATH")
export WINDOWSSDKDIR="${VSPATH}/SDK"
export VCINSTALLDIR="${VSPATH}/VC"

CRTREG="Microsoft\\Microsoft SDKs\\Windows\\v10.0"
UniversalCRTSdkDir=$(regquery "$CRTREG" InstallationFolder)
UniversalCRTSdkDir=$(fixpath "$UniversalCRTSdkDir")
UCRTVersion=$(regquery "$CRTREG" ProductVersion)
UCRTVersion=$(cd "${UniversalCRTSdkDir}/include"; ls -d "${UCRTVersion}"* | tail -1)

VCVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt")
REDISTVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCRedistVersion.default.txt")
export WIN32_REDIST_DIR="${VCINSTALLDIR}/Redist/MSVC/${REDISTVER}/${m}/Microsoft.VC141.CRT"
export WIN_UCRT_REDIST_DIR="${UniversalCRTSdkDir}/Redist/ucrt/DLLs/${m}"

if [ "$m" == "x86" ]; then
PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/HostX64/x86"
PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Hostx86/x86"
fi
PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/HostX64/x64"
PATH="${PATH}:${UniversalCRTSdkDir}/bin/${UCRTVersion}/x64"
PATH="${PATH}:${UniversalCRTSdkDir}/bin/${UCRTVersion}/x86"
PATH="${PATH}:${WIN32_REDIST_DIR}"
export PATH

INCLUDE="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/ATLMFC/include"
INCLUDE="${INCLUDE}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/include"
INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/ucrt"
INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/shared"
INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/um"
INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/winrt"
INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/cppwinrt"
export INCLUDE

LIB="${VCINSTALLDIR}/lib/${m}"
LIB="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/lib/${m}"
LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/ucrt/${m}"
LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/um/${m}"
export LIB

export GYP_MSVS_OVERRIDE_PATH="${VSPATH}"
export GYP_MSVS_VERSION=$(vswhere -latest -requires "$VSCOMPONENT" -property catalog_productLineVersion)
3 changes: 3 additions & 0 deletions coreconf/nspr.sh
Expand Up @@ -32,6 +32,9 @@ nspr_build()
if [ "$opt_build" = 1 ]; then
extra_params+=(--disable-debug --enable-optimize)
fi
if [ "$target_arch" = "x64" ]; then
extra_params+=(--enable-64bit)
fi

echo "NSPR [1/3] configure ..."
pushd "$nspr_dir" >/dev/null
Expand Down

0 comments on commit 762709e

Please sign in to comment.