summaryrefslogtreecommitdiff
path: root/nss/build.sh
diff options
context:
space:
mode:
Diffstat (limited to 'nss/build.sh')
-rwxr-xr-xnss/build.sh266
1 files changed, 137 insertions, 129 deletions
diff --git a/nss/build.sh b/nss/build.sh
index 5af3d34..0a9ce76 100755
--- a/nss/build.sh
+++ b/nss/build.sh
@@ -1,4 +1,10 @@
-#!/bin/bash
+#!/usr/bin/env bash
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+################################################################################
+#
# This script builds NSS with gyp and ninja.
#
# This build system is still under development. It does not yet support all
@@ -6,41 +12,27 @@
set -e
-source $(dirname $0)/coreconf/nspr.sh
+cwd=$(cd $(dirname $0); pwd -P)
+source "$cwd"/coreconf/nspr.sh
+source "$cwd"/coreconf/sanitizers.sh
+GYP=${GYP:-gyp}
# Usage info
-show_help() {
-cat << EOF
-
-Usage: ${0##*/} [-hcgv] [-j <n>] [--test] [--fuzz] [--scan-build[=output]]
- [-m32] [--opt|-o] [--asan] [--ubsan] [--sancov[=edge|bb|func]]
- [--pprof] [--msan]
-
-This script builds NSS with gyp and ninja.
-
-This build system is still under development. It does not yet support all
-the features or platforms that NSS supports.
-
-NSS build tool options:
-
- -h display this help and exit
- -c clean before build
- -g force a rebuild of gyp (and NSPR, because why not)
- -j <n> run at most <n> concurrent jobs
- -v verbose build
- -m32 do a 32-bit build on a 64-bit system
- --test ignore map files and export everything we have
- --fuzz enable fuzzing mode. this always enables test builds
- --scan-build run the build with scan-build (scan-build has to be in the path)
- --scan-build=/out/path sets the output path for scan-build
- --opt|-o do an opt build
- --asan do an asan build
- --ubsan do an ubsan build
- --msan do an msan build
- --sancov do sanitize coverage builds
- --sancov=func sets coverage to function level for example
- --pprof build with gperftool support
-EOF
+show_help()
+{
+ cat "$cwd"/help.txt
+}
+
+run_verbose()
+{
+ if [ "$verbose" = 1 ]; then
+ echo "$@"
+ exec 3>&1
+ else
+ exec 3>/dev/null
+ fi
+ "$@" 1>&3 2>&3
+ exec 3>&-
}
if [ -n "$CCC" ] && [ -z "$CXX" ]; then
@@ -51,154 +43,170 @@ opt_build=0
build_64=0
clean=0
rebuild_gyp=0
+rebuild_nspr=0
target=Debug
verbose=0
fuzz=0
+fuzz_tls=0
+fuzz_oss=0
+no_local_nspr=0
+armhf=0
-# parse parameters to store in config
-params=$(echo "$*" | perl -pe 's/-c|-v|-g|-j [0-9]*|-h//g' | perl -pe 's/^\s*(.*?)\s*$/\1/')
-params=$(echo "$params $CC $CCC" | tr " " "\n" | perl -pe '/^\s*$/d')
-params=$(echo "${params[*]}" | sort)
-
-cwd=$(cd $(dirname $0); pwd -P)
-dist_dir="$cwd/../dist"
+gyp_params=(--depth="$cwd" --generator-output=".")
+nspr_params=()
+ninja_params=()
# try to guess sensible defaults
-arch=$(python "$cwd/coreconf/detect_host_arch.py")
+arch=$(python "$cwd"/coreconf/detect_host_arch.py)
if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
build_64=1
+elif [ "$arch" = "arm" ]; then
+ armhf=1
fi
-gyp_params=()
-ninja_params=()
-scanbuild=()
-
-enable_fuzz()
-{
- fuzz=1
- nspr_sanitizer asan
- nspr_sanitizer ubsan
- nspr_sanitizer sancov edge
- gyp_params+=(-Duse_asan=1)
- gyp_params+=(-Duse_ubsan=1)
- gyp_params+=(-Duse_sancov=edge)
-
- # Adding debug symbols even for opt builds.
- nspr_opt+=(--enable-debug-symbols)
-}
-
# parse command line arguments
while [ $# -gt 0 ]; do
case $1 in
-c) clean=1 ;;
- -g) rebuild_gyp=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) ;;
- --fuzz) gyp_params+=(-Dtest_build=1 -Dfuzz=1); enable_fuzz ;;
- --scan-build) scanbuild=(scan-build) ;;
- --scan-build=?*) scanbuild=(scan-build -o "${1#*=}") ;;
+ --fuzz) fuzz=1 ;;
+ --fuzz=oss) fuzz=1; fuzz_oss=1 ;;
+ --fuzz=tls) fuzz=1; fuzz_tls=1 ;;
+ --scan-build) enable_scanbuild ;;
+ --scan-build=?*) enable_scanbuild "${1#*=}" ;;
--opt|-o) opt_build=1 ;;
-m32|--m32) build_64=0 ;;
- --asan) gyp_params+=(-Duse_asan=1); nspr_sanitizer asan ;;
- --ubsan) gyp_params+=(-Duse_ubsan=1); nspr_sanitizer ubsan ;;
- --sancov) gyp_params+=(-Duse_sancov=edge); nspr_sanitizer sancov edge ;;
- --sancov=?*) gyp_params+=(-Duse_sancov="${1#*=}"); nspr_sanitizer sancov "${1#*=}" ;;
+ --asan) enable_sanitizer asan ;;
+ --msan) enable_sanitizer msan ;;
+ --ubsan) enable_ubsan ;;
+ --ubsan=?*) enable_ubsan "${1#*=}" ;;
+ --sancov) enable_sancov ;;
+ --sancov=?*) enable_sancov "${1#*=}" ;;
--pprof) gyp_params+=(-Duse_pprof=1) ;;
- --msan) gyp_params+=(-Duse_msan=1); nspr_sanitizer msan ;;
- *) show_help; exit ;;
+ --ct-verif) gyp_params+=(-Dct_verif=1) ;;
+ --disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
+ --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
+ --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
+ --with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;;
+ --system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;;
+ *) show_help; exit 2 ;;
esac
shift
done
-if [ "$opt_build" = "1" ]; then
+if [ "$opt_build" = 1 ]; then
target=Release
- nspr_opt+=(--disable-debug --enable-optimize)
else
target=Debug
fi
-if [ "$build_64" == "1" ]; then
- nspr_opt+=(--enable-64bit)
-else
+if [ "$build_64" = 1 ]; then
+ nspr_params+=(--enable-64bit)
+elif [ ! "$armhf" = 1 ]; then
gyp_params+=(-Dtarget_arch=ia32)
- nspr_opt+=(--enable-x32)
+fi
+if [ "$fuzz" = 1 ]; then
+ source "$cwd"/coreconf/fuzz.sh
fi
-# clone fuzzing stuff
-if [ "$fuzz" = "1" ]; then
- [ $verbose = 0 ] && exec 3>/dev/null || exec 3>&1
+# set paths
+target_dir="$cwd"/out/$target
+mkdir -p "$target_dir"
+dist_dir="$cwd"/../dist
+dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P)
+gyp_params+=(-Dnss_dist_dir="$dist_dir")
- echo "[1/2] Cloning libFuzzer files ..."
- $cwd/fuzz/clone_libfuzzer.sh 1>&3 2>&3
+# -c = clean first
+if [ "$clean" = 1 ]; then
+ nspr_clean
+ rm -rf "$cwd"/out
+ rm -rf "$dist_dir"
+fi
- echo "[2/2] Cloning fuzzing corpus ..."
- $cwd/fuzz/clone_corpus.sh 1>&3 2>&3
+# This saves a canonical representation of arguments that we are passing to gyp
+# or the NSPR build so that we can work out if a rebuild is needed.
+# Caveat: This can fail for arguments that are position-dependent.
+# e.g., "-e 2 -f 1" and "-e 1 -f 2" canonicalize the same.
+check_config()
+{
+ local newconf="$1".new oldconf="$1"
+ shift
+ mkdir -p $(dirname "$newconf")
+ echo CC="$CC" >"$newconf"
+ echo CCC="$CCC" >>"$newconf"
+ echo CXX="$CXX" >>"$newconf"
+ for i in "$@"; do echo $i; done | sort >>"$newconf"
+
+ # Note: The following diff fails if $oldconf isn't there as well, which
+ # happens if we don't have a previous successful build.
+ ! diff -q "$newconf" "$oldconf" >/dev/null 2>&1
+}
- exec 3>&-
-fi
+gyp_config="$cwd"/out/gyp_config
+nspr_config="$cwd"/out/$target/nspr_config
-# check if we have to rebuild gyp
-if [ "$params" != "$(cat $cwd/out/config 2>/dev/null)" -o "$rebuild_gyp" == 1 -o "$clean" == 1 ]; then
+# If we don't have a build directory make sure that we rebuild.
+if [ ! -d "$target_dir" ]; then
+ rebuild_nspr=1
rebuild_gyp=1
- rm -rf "$cwd/../nspr/$target" # force NSPR to rebuild
+elif [ ! -d "$dist_dir"/$target ]; then
+ rebuild_nspr=1
fi
-# set paths
-target_dir="$cwd/out/$target"
+# Update NSPR ${C,CXX,LD}FLAGS.
+nspr_set_flags $sanitizer_flags
-# get the realpath of $dist_dir
-dist_dir=$(mkdir -p $dist_dir; cd $dist_dir; pwd -P)
+if check_config "$nspr_config" "${nspr_params[@]}" \
+ nspr_cflags="$nspr_cflags" \
+ nspr_cxxflags="$nspr_cxxflags" \
+ nspr_ldflags="$nspr_ldflags"; then
+ rebuild_nspr=1
+fi
-# get object directory
-obj_dir="$dist_dir/$target"
-gyp_params+=(-Dnss_dist_dir=$dist_dir)
-gyp_params+=(-Dnss_dist_obj_dir=$obj_dir)
-gyp_params+=(-Dnspr_lib_dir=$obj_dir/lib)
-gyp_params+=(-Dnspr_include_dir=$obj_dir/include/nspr)
+# Forward sanitizer flags.
+if [ ! -z "$sanitizer_flags" ]; then
+ gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
+fi
-# -c = clean first
-if [ "$clean" = 1 ]; then
- rm -rf "$cwd/out"
- rm -rf "$cwd/../nspr/$target"
- rm -rf "$dist_dir"
+if check_config "$gyp_config" "${gyp_params[@]}"; then
+ rebuild_gyp=1
fi
# save the chosen target
-mkdir -p $dist_dir
-echo $target > $dist_dir/latest
+mkdir -p "$dist_dir"
+echo $target > "$dist_dir"/latest
-# pass on CC and CCC
-if [ "${#scanbuild[@]}" -gt 0 ]; then
- if [ -n "$CC" ]; then
- scanbuild+=(--use-cc="$CC")
+if [[ "$rebuild_nspr" = 1 && "$no_local_nspr" = 0 ]]; then
+ nspr_build "${nspr_params[@]}"
+ mv -f "$nspr_config".new "$nspr_config"
+fi
+if [ "$rebuild_gyp" = 1 ]; then
+ if ! hash ${GYP} 2> /dev/null; then
+ echo "Please install gyp" 1>&2
+ exit 1
fi
- if [ -n "$CCC" ]; then
- scanbuild+=(--use-c++="$CCC")
+ # These extra arguments aren't used in determining whether to rebuild.
+ obj_dir="$dist_dir"/$target
+ gyp_params+=(-Dnss_dist_obj_dir=$obj_dir)
+ if [ "$no_local_nspr" = 0 ]; then
+ set_nspr_path "$obj_dir/include/nspr:$obj_dir/lib"
fi
- fi
-
-# These steps can take a while, so don't overdo them.
-# Force a redo with -g.
-if [ "$rebuild_gyp" = 1 -o ! -d "$target_dir" ]; then
- build_nspr $verbose
- # Run gyp.
- [ $verbose = 1 ] && set -v -x
- "${scanbuild[@]}" gyp -f ninja "${gyp_params[@]}" --depth="$cwd" \
- --generator-output="." "$cwd/nss.gyp"
- [ $verbose = 1 ] && set +v +x
+ run_verbose run_scanbuild ${GYP} -f ninja "${gyp_params[@]}" "$cwd"/nss.gyp
- # Store used parameters for next run.
- echo "$params" > "$cwd/out/config"
+ mv -f "$gyp_config".new "$gyp_config"
fi
# Run ninja.
-if which ninja >/dev/null 2>&1; then
- ninja=(ninja)
-elif which ninja-build >/dev/null 2>&1; then
- ninja=(ninja-build)
+if hash ninja 2>/dev/null; then
+ ninja=ninja
+elif hash ninja-build 2>/dev/null; then
+ ninja=ninja-build
else
echo "Please install ninja" 1>&2
exit 1
fi
-"${scanbuild[@]}" $ninja -C "$target_dir" "${ninja_params[@]}"
+run_scanbuild $ninja -C "$target_dir" "${ninja_params[@]}"