1#!/usr/bin/env bash 2# 3# This Source Code Form is subject to the terms of the Mozilla Public 4# License, v. 2.0. If a copy of the MPL was not distributed with this 5# file, You can obtain one at http://mozilla.org/MPL/2.0/. 6################################################################################ 7# 8# This script builds NSS with gyp and ninja. 9# 10# This build system is still under development. It does not yet support all 11# the features or platforms that NSS supports. 12 13set -e 14 15cwd=$(cd $(dirname $0); pwd -P) 16source "$cwd"/coreconf/nspr.sh 17source "$cwd"/coreconf/sanitizers.sh 18GYP=${GYP:-gyp} 19 20# Usage info 21show_help() 22{ 23 cat "$cwd"/help.txt 24} 25 26run_verbose() 27{ 28 if [ "$verbose" = 1 ]; then 29 echo "$@" 30 exec 3>&1 31 else 32 exec 3>/dev/null 33 fi 34 "$@" 1>&3 2>&3 35 exec 3>&- 36} 37 38if [ -n "$CCC" ] && [ -z "$CXX" ]; then 39 export CXX="$CCC" 40fi 41 42opt_build=0 43build_64=0 44clean=0 45rebuild_gyp=0 46rebuild_nspr=0 47target=Debug 48verbose=0 49fuzz=0 50fuzz_tls=0 51fuzz_oss=0 52no_local_nspr=0 53armhf=0 54 55gyp_params=(--depth="$cwd" --generator-output=".") 56nspr_params=() 57ninja_params=() 58 59# try to guess sensible defaults 60arch=$(python "$cwd"/coreconf/detect_host_arch.py) 61if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then 62 build_64=1 63elif [ "$arch" = "arm" ]; then 64 armhf=1 65fi 66 67# parse command line arguments 68while [ $# -gt 0 ]; do 69 case $1 in 70 -c) clean=1 ;; 71 -cc) clean_only=1 ;; 72 --gyp|-g) rebuild_gyp=1 ;; 73 --nspr) nspr_clean; rebuild_nspr=1 ;; 74 -j) ninja_params+=(-j "$2"); shift ;; 75 -v) ninja_params+=(-v); verbose=1 ;; 76 --test) gyp_params+=(-Dtest_build=1) ;; 77 --clang) export CC=clang; export CCC=clang++; export CXX=clang++ ;; 78 --gcc) export CC=gcc; export CCC=g++; export CXX=g++ ;; 79 --fuzz) fuzz=1 ;; 80 --fuzz=oss) fuzz=1; fuzz_oss=1 ;; 81 --fuzz=tls) fuzz=1; fuzz_tls=1 ;; 82 --scan-build) enable_scanbuild ;; 83 --scan-build=?*) enable_scanbuild "${1#*=}" ;; 84 --opt|-o) opt_build=1 ;; 85 -m32|--m32) build_64=0 ;; 86 --asan) enable_sanitizer asan ;; 87 --msan) enable_sanitizer msan ;; 88 --ubsan) enable_ubsan ;; 89 --ubsan=?*) enable_ubsan "${1#*=}" ;; 90 --sancov) enable_sancov ;; 91 --sancov=?*) enable_sancov "${1#*=}" ;; 92 --pprof) gyp_params+=(-Duse_pprof=1) ;; 93 --ct-verif) gyp_params+=(-Dct_verif=1) ;; 94 --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;; 95 --disable-tests) gyp_params+=(-Ddisable_tests=1) ;; 96 --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;; 97 --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;; 98 --with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;; 99 --system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;; 100 --enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;; 101 --enable-fips) gyp_params+=(-Ddisable_fips=0) ;; 102 *) show_help; exit 2 ;; 103 esac 104 shift 105done 106 107if [ "$opt_build" = 1 ]; then 108 target=Release 109else 110 target=Debug 111fi 112if [ "$build_64" = 1 ]; then 113 nspr_params+=(--enable-64bit) 114elif [ ! "$armhf" = 1 ]; then 115 gyp_params+=(-Dtarget_arch=ia32) 116fi 117if [ "$fuzz" = 1 ]; then 118 source "$cwd"/coreconf/fuzz.sh 119fi 120 121# set paths 122target_dir="$cwd"/out/$target 123mkdir -p "$target_dir" 124dist_dir="$cwd"/../dist 125dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P) 126gyp_params+=(-Dnss_dist_dir="$dist_dir") 127 128# -c = clean first 129if [ "$clean" = 1 -o "$clean_only" = 1 ]; then 130 nspr_clean 131 rm -rf "$cwd"/out 132 rm -rf "$dist_dir" 133 # -cc = only clean, don't build 134 if [ "$clean_only" = 1 ]; then 135 echo "Cleaned" 136 exit 0 137 fi 138fi 139 140# This saves a canonical representation of arguments that we are passing to gyp 141# or the NSPR build so that we can work out if a rebuild is needed. 142# Caveat: This can fail for arguments that are position-dependent. 143# e.g., "-e 2 -f 1" and "-e 1 -f 2" canonicalize the same. 144check_config() 145{ 146 local newconf="$1".new oldconf="$1" 147 shift 148 mkdir -p $(dirname "$newconf") 149 echo CC="$CC" >"$newconf" 150 echo CCC="$CCC" >>"$newconf" 151 echo CXX="$CXX" >>"$newconf" 152 for i in "$@"; do echo $i; done | sort >>"$newconf" 153 154 # Note: The following diff fails if $oldconf isn't there as well, which 155 # happens if we don't have a previous successful build. 156 ! diff -q "$newconf" "$oldconf" >/dev/null 2>&1 157} 158 159gyp_config="$cwd"/out/gyp_config 160nspr_config="$cwd"/out/$target/nspr_config 161 162# If we don't have a build directory make sure that we rebuild. 163if [ ! -d "$target_dir" ]; then 164 rebuild_nspr=1 165 rebuild_gyp=1 166elif [ ! -d "$dist_dir"/$target ]; then 167 rebuild_nspr=1 168fi 169 170# Update NSPR ${C,CXX,LD}FLAGS. 171nspr_set_flags $sanitizer_flags 172 173if check_config "$nspr_config" "${nspr_params[@]}" \ 174 nspr_cflags="$nspr_cflags" \ 175 nspr_cxxflags="$nspr_cxxflags" \ 176 nspr_ldflags="$nspr_ldflags"; then 177 rebuild_nspr=1 178fi 179 180# Forward sanitizer flags. 181if [ ! -z "$sanitizer_flags" ]; then 182 gyp_params+=(-Dsanitizer_flags="$sanitizer_flags") 183fi 184 185if check_config "$gyp_config" "${gyp_params[@]}"; then 186 rebuild_gyp=1 187fi 188 189# save the chosen target 190mkdir -p "$dist_dir" 191echo $target > "$dist_dir"/latest 192 193if [[ "$rebuild_nspr" = 1 && "$no_local_nspr" = 0 ]]; then 194 nspr_build "${nspr_params[@]}" 195 mv -f "$nspr_config".new "$nspr_config" 196fi 197if [ "$rebuild_gyp" = 1 ]; then 198 if ! hash ${GYP} 2> /dev/null; then 199 echo "Please install gyp" 1>&2 200 exit 1 201 fi 202 # These extra arguments aren't used in determining whether to rebuild. 203 obj_dir="$dist_dir"/$target 204 gyp_params+=(-Dnss_dist_obj_dir=$obj_dir) 205 if [ "$no_local_nspr" = 0 ]; then 206 set_nspr_path "$obj_dir/include/nspr:$obj_dir/lib" 207 fi 208 209 run_verbose run_scanbuild ${GYP} -f ninja "${gyp_params[@]}" "$cwd"/nss.gyp 210 211 mv -f "$gyp_config".new "$gyp_config" 212fi 213 214# Run ninja. 215if hash ninja 2>/dev/null; then 216 ninja=ninja 217elif hash ninja-build 2>/dev/null; then 218 ninja=ninja-build 219else 220 echo "Please install ninja" 1>&2 221 exit 1 222fi 223run_scanbuild $ninja -C "$target_dir" "${ninja_params[@]}" 224