build.sh 7.8 KB

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