tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

build.sh (9183B)


      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 
     13 set -e
     14 
     15 cwd=$(cd $(dirname $0); pwd -P)
     16 dist_dir="$cwd/../dist"
     17 argsfile="$dist_dir/build_args"
     18 source "$cwd/coreconf/nspr.sh"
     19 source "$cwd/coreconf/sanitizers.sh"
     20 GYP=${GYP:-gyp}
     21 
     22 # Usage info
     23 show_help()
     24 {
     25    cat "$cwd/help.txt"
     26 }
     27 
     28 run_verbose()
     29 {
     30    if [ "$verbose" = 1 ]; then
     31        echo "$@"
     32        exec 3>&1
     33        "$@" 1>&3 2>&3
     34        exec 3>&-
     35    else
     36        "$@" >/dev/null
     37    fi
     38 }
     39 
     40 # The prehistoric bash on Mac doesn't support @Q quoting.
     41 # The consequences aren't that serious, unless there are odd arrangements of spaces.
     42 if /usr/bin/env bash -c 'x=1;echo "${x@Q}"' >/dev/null 2>&1; then
     43    Q() { echo "${@@Q}"; }
     44 else
     45    Q() { echo "$@"; }
     46 fi
     47 
     48 if [ -n "$CCC" ] && [ -z "$CXX" ]; then
     49    export CXX="$CCC"
     50 fi
     51 
     52 opt_build=0
     53 build_64=0
     54 clean=0
     55 rebuild_gyp=0
     56 rebuild_nspr=0
     57 build_nspr_tests=0
     58 run_nspr_tests=0
     59 exit_after_nspr=0
     60 target=Debug
     61 verbose=0
     62 fuzz=0
     63 fuzz_tls=0
     64 fuzz_oss=0
     65 no_local_nspr=0
     66 sslkeylogfile=1
     67 
     68 gyp_params=(--depth="$cwd" --generator-output=".")
     69 ninja_params=()
     70 
     71 # Assume that MSVC is wanted if this is running on windows.
     72 platform=$(uname -s)
     73 if [ "${platform%-*}" = "MINGW32_NT" -o "${platform%-*}" = "MINGW64_NT" -o "${platform%%-*}" = "MSYS_NT" ]; then
     74    msvc=1
     75 fi
     76 
     77 # Parse command line arguments.
     78 all_args=("$@")
     79 while [ $# -gt 0 ]; do
     80    case "$1" in
     81        --rebuild)
     82            if [[ ! -e "$argsfile" ]]; then
     83                echo "Unable to rebuild" 1>&2
     84                exit 2
     85            fi
     86            IFS=$'\r\n' GLOBIGNORE='*' command eval  'previous_args=($(<"$argsfile"))'
     87            exec /usr/bin/env bash -c "$(Q "$0")"' "$@"' "$0" "${previous_args[@]}"
     88            ;;
     89        -c) clean=1 ;;
     90        -cc) clean_only=1 ;;
     91        -v) ninja_params+=(-v); verbose=1 ;;
     92        -j) ninja_params+=(-j "$2"); shift ;;
     93        --gyp|-g) rebuild_gyp=1 ;;
     94        --opt|-o) opt_build=1 ;;
     95        -m32|--m32) target_arch=ia32; echo 'Warning: use -t instead of -m32' 1>&2 ;;
     96        -t|--target) target_arch="$2"; shift ;;
     97        --target=*) target_arch="${1#*=}" ;;
     98        --build-tools-cc=*) build_tools_cc="${1#*=}" ;;
     99        --clang) export CC=clang; export CCC=clang++; export CXX=clang++; msvc=0 ;;
    100        --gcc) export CC=gcc; export CCC=g++; export CXX=g++; msvc=0 ;;
    101        --msvc) msvc=1 ;;
    102        --scan-build) enable_scanbuild  ;;
    103        --scan-build=?*) enable_scanbuild "${1#*=}" ;;
    104        --disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
    105        --pprof) gyp_params+=(-Duse_pprof=1) ;;
    106        --asan) enable_sanitizer asan ;;
    107        --msan) enable_sanitizer msan ;;
    108        --tsan) enable_sanitizer tsan ;;
    109        --sourcecov) enable_sourcecov ;;
    110        --ubsan) enable_ubsan ;;
    111        --ubsan=?*) enable_ubsan "${1#*=}" ;;
    112        --fuzz) fuzz=1 ;;
    113        --fuzz=oss) fuzz=1; fuzz_oss=1 ;;
    114        --fuzz=tls) fuzz=1; fuzz_tls=1 ;;
    115        --sancov) enable_sancov; gyp_params+=(-Dcoverage=1) ;;
    116        --sancov=?*) enable_sancov "${1#*=}"; gyp_params+=(-Dcoverage=1) ;;
    117        --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
    118        --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
    119        --static) gyp_params+=(-Dstatic_libs=1) ;;
    120        --ct-verif) gyp_params+=(-Dct_verif=1) ;;
    121        --nspr) nspr_clean; rebuild_nspr=1 ;;
    122        --nspr-test-build) build_nspr_tests=1 ;;
    123        --nspr-test-run) run_nspr_tests=1 ;;
    124        --nspr-only) exit_after_nspr=1 ;;
    125        --with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;;
    126        --system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;;
    127        --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
    128        --enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
    129        --fips-module-id) gyp_params+=(-Dfips_module_id="$2"); shift ;;
    130        --fips-module-id=?*) gyp_params+=(-Dfips_module_id="${1#*=}") ;;
    131        --enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
    132        --mozpkix-only) gyp_params+=(-Dmozpkix_only=1 -Ddisable_tests=1 -Dsign_libs=0) ;;
    133        --disable-keylog) sslkeylogfile=0 ;;
    134        --enable-legacy-db) gyp_params+=(-Ddisable_dbm=0) ;;
    135        --mozilla-central) gyp_params+=(-Dmozilla_central=1) ;;
    136        --python) python="$2"; shift ;;
    137        --python=*) python="${1#*=}" ;;
    138        -D*) gyp_params+=("$1") ;;
    139        *) show_help; exit 2 ;;
    140    esac
    141    shift
    142 done
    143 
    144 if [ "$opt_build" = 1 ] && [ "$fuzz" = 1 ]; then
    145    echo "Specifiying --opt with --fuzz is not supported." >&2
    146    exit 1
    147 fi
    148 
    149 if [ -n "${sanitizers["tsan"]:-}" ] && ([ "$CC" = "gcc" ] ||
    150                                        [ "$CCC" = "g++" ] ||
    151                                        [ "$CXX" = "g++" ]); then
    152    echo "Specifying --tsan with gcc results in false positives whilst building NSPR." >&2
    153    exit 1
    154 fi
    155 
    156 if [ -n "$python" ]; then
    157    gyp_params+=(-Dpython="$python")
    158 fi
    159 
    160 if [ -z "$target_arch" ]; then
    161    # Assume that the target architecture is the same as the host by default.
    162    host_arch=$(${python:-python3} "$cwd/coreconf/detect_host_arch.py")
    163    target_arch=$host_arch
    164 fi
    165 
    166 # Set the target architecture and build type.
    167 gyp_params+=(-Dtarget_arch="$target_arch")
    168 if [ "$opt_build" = 1 ]; then
    169    target=Release
    170 else
    171    target=Debug
    172 fi
    173 
    174 # When cross-compiling, system zlib for the target architecture may not be available
    175 if [[ -n "$CC" && -n "$build_tools_cc" && "$CC" != "$build_tools_cc" ]]; then
    176    gyp_params+=(-Duse_system_zlib=0 -Dsign_libs=0)
    177 fi
    178 
    179 gyp_params+=(-Denable_sslkeylogfile="$sslkeylogfile")
    180 
    181 # Do special setup.
    182 if [ "$fuzz" = 1 ]; then
    183    source "$cwd/coreconf/fuzz.sh"
    184 fi
    185 nspr_set_flags $sanitizer_flags
    186 if [ ! -z "$sanitizer_flags" ]; then
    187    gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
    188 fi
    189 
    190 if [ "$msvc" = 1 ]; then
    191    source "$cwd/coreconf/msvc.sh"
    192 fi
    193 
    194 # -c = clean first
    195 if [ "$clean" = 1 -o "$clean_only" = 1 ]; then
    196    nspr_clean
    197    rm -rf "$cwd/out"
    198    rm -rf "$dist_dir"
    199    # -cc = only clean, don't build
    200    if [ "$clean_only" = 1 ]; then
    201        echo "Cleaned"
    202        exit 0
    203    fi
    204 fi
    205 
    206 # Setup build paths.
    207 target_dir="$cwd/out/$target"
    208 mkdir -p "$target_dir"
    209 dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P)
    210 gyp_params+=(-Dnss_dist_dir="$dist_dir")
    211 
    212 # This saves a canonical representation of arguments that we are passing to gyp
    213 # or the NSPR build so that we can work out if a rebuild is needed.
    214 # Caveat: This can fail for arguments that are position-dependent.
    215 # e.g., "-e 2 -f 1" and "-e 1 -f 2" canonicalize the same.
    216 check_config()
    217 {
    218    local newconf="$1".new oldconf="$1"
    219    shift
    220    mkdir -p $(dirname "$newconf")
    221    echo CC="$(Q "$CC")" >"$newconf"
    222    echo CCC="$(Q "$CCC")" >>"$newconf"
    223    echo CXX="$(Q "$CXX")" >>"$newconf"
    224    echo target_arch="$(Q "$target_arch")" >>"$newconf"
    225    for i in "$@"; do echo "$i"; done | sort >>"$newconf"
    226 
    227    # Note: The following diff fails if $oldconf isn't there as well, which
    228    # happens if we don't have a previous successful build.
    229    ! diff -q "$newconf" "$oldconf" >/dev/null 2>&1
    230 }
    231 
    232 gyp_config="$cwd/out/gyp_config"
    233 nspr_config="$cwd/out/$target/nspr_config"
    234 
    235 # Now check what needs to be rebuilt.
    236 # If we don't have a build directory make sure that we rebuild.
    237 if [ ! -d "$target_dir" ]; then
    238    rebuild_nspr=1
    239    rebuild_gyp=1
    240 elif [ ! -d "$dist_dir/$target" ]; then
    241    rebuild_nspr=1
    242 fi
    243 
    244 if check_config "$nspr_config" \
    245                 nspr_cflags="$(Q "$nspr_cflags")" \
    246                 nspr_cxxflags="$(Q "$nspr_cxxflags")" \
    247                 nspr_ldflags="$(Q "$nspr_ldflags")"; then
    248    rebuild_nspr=1
    249 fi
    250 
    251 if check_config "$gyp_config" "$(Q "${gyp_params[@]}")"; then
    252    rebuild_gyp=1
    253 fi
    254 
    255 # Save the chosen target.
    256 echo "$target" > "$dist_dir/latest"
    257 for i in "${all_args[@]}"; do echo "$i"; done > "$argsfile"
    258 
    259 # Build.
    260 # NSPR.
    261 if [[ "$rebuild_nspr" = 1 && "$no_local_nspr" = 0 ]]; then
    262    nspr_clean
    263    nspr_build
    264    mv -f "$nspr_config.new" "$nspr_config"
    265 fi
    266 
    267 if [ "$exit_after_nspr" = 1 ]; then
    268  exit 0
    269 fi
    270 
    271 # gyp.
    272 if [ "$rebuild_gyp" = 1 ]; then
    273    if ! hash "$GYP" 2> /dev/null; then
    274        echo "Building NSS requires an installation of gyp: https://gyp.gsrc.io/" 1>&2
    275        exit 3
    276    fi
    277    # These extra arguments aren't used in determining whether to rebuild.
    278    obj_dir="$dist_dir/$target"
    279    gyp_params+=(-Dnss_dist_obj_dir="$obj_dir")
    280    if [ "$no_local_nspr" = 0 ]; then
    281        set_nspr_path "$obj_dir/include/nspr:$obj_dir/lib"
    282    fi
    283 
    284    run_verbose run_scanbuild ${GYP} -f ninja "${gyp_params[@]}" "$cwd/nss.gyp"
    285 
    286    mv -f "$gyp_config.new" "$gyp_config"
    287 fi
    288 
    289 # ninja.
    290 if hash ninja-build 2>/dev/null; then
    291    ninja=ninja-build
    292 elif hash ninja 2>/dev/null; then
    293    ninja=ninja
    294 else
    295    echo "Building NSS requires an installation of ninja: https://ninja-build.org/" 1>&2
    296    exit 3
    297 fi
    298 run_scanbuild "$ninja" -C "$target_dir" "${ninja_params[@]}"