PageRenderTime 2879ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/jni/openssl/check-all-builds.sh

https://gitlab.com/ayham-hassan/Signal-Android
Shell | 647 lines | 554 code | 44 blank | 49 comment | 15 complexity | d92c09c071dca73a1de5eff763d45181 MD5 | raw file
  1. #!/bin/sh
  2. #
  3. set -e
  4. export LANG=C
  5. export LC_ALL=C
  6. PROGDIR=$(dirname "$0")
  7. PROGNAME=$(basename "$0")
  8. panic () {
  9. echo "ERROR: $@"
  10. exit 1
  11. }
  12. VERBOSE=1
  13. # Dump message is $VERBOSE >= $1
  14. # $1+: message.
  15. dump_n () {
  16. local LOG_LEVEL=$1
  17. shift
  18. if [ "$VERBOSE" -ge "$LOG_LEVEL" ]; then
  19. printf "%s\n" "$@"
  20. fi
  21. }
  22. # Dump a message unless --quiet is used.
  23. # $1+: message.
  24. dump () {
  25. dump_n 1 "$@"
  26. }
  27. # Dump a message if --verbose is used only.
  28. # $1+: message.
  29. log () {
  30. dump_n 2 "$@"
  31. }
  32. # Run a command silently, unless --verbose or '--verbose --verbose'
  33. # is used.
  34. # $1+: Command
  35. # Return: command status.
  36. run () {
  37. log "COMMAND: $*"
  38. case $VERBOSE in
  39. 0)
  40. "$@" >/dev/null 2>&1 || return $?
  41. ;;
  42. 1)
  43. "$@" >/dev/null || return $?
  44. ;;
  45. *)
  46. "$@" || return $?
  47. ;;
  48. esac
  49. }
  50. # $1: string
  51. # Out: input string, with capital letters replaced by small ones.
  52. tolower () {
  53. echo "$1" | tr '[A-Z]' '[a-z]'
  54. }
  55. # Return value of a given variable.
  56. # $1: Variable name
  57. var_value () {
  58. eval printf \"%s\" \"\$$1\"
  59. }
  60. # Remove some items from a list
  61. # $1: input space-separated list
  62. # $2: space-separated list of items to remove from 1
  63. # Out: items of $1 without items of $2
  64. filter_out () {
  65. local TMP=$(mktemp)
  66. local RESULT
  67. printf "" > $TMP
  68. echo "$2" | tr ' ' '\n' > $TMP
  69. RESULT=$(echo "$1" | tr ' ' '\n' | fgrep -x -v -f $TMP | tr '\n' ' ')
  70. rm -f $TMP
  71. echo "$RESULT"
  72. }
  73. src_to_obj () {
  74. case $1 in
  75. *.c)
  76. echo ${1%%.c}.o
  77. ;;
  78. *.S)
  79. echo ${1%%.S}.o
  80. ;;
  81. *)
  82. echo $1
  83. ;;
  84. esac
  85. }
  86. # Determine host operating system.
  87. HOST_OS=$(uname -s)
  88. case $HOST_OS in
  89. Linux)
  90. HOST_OS=linux
  91. ;;
  92. Darwin)
  93. HOST_OS=darwin
  94. ;;
  95. esac
  96. # Determine host architecture
  97. HOST_ARCH=$(uname -m)
  98. case $HOST_ARCH in
  99. i?86)
  100. HOST_ARCH=x86
  101. ;;
  102. esac
  103. ANDROID_HOST_TAG=$HOST_OS-$HOST_ARCH
  104. case $ANDROID_HOST_TAG in
  105. linux-x86_64|darwin-x86-64)
  106. ANDROID_HOST_TAG=$HOST_OS-x86
  107. ;;
  108. *)
  109. panic "Sorry, this script can only run on 64-bit Linux or Darwin"
  110. esac
  111. # Determine username of cores
  112. case $HOST_OS in
  113. linux)
  114. NUM_CORES=$(grep -c "processor" /proc/cpuinfo)
  115. ;;
  116. darwin)
  117. NUM_CORES=$(sysctl -n hw.ncpu)
  118. ;;
  119. *)
  120. NUM_CORES=1
  121. ;;
  122. esac
  123. # The list of supported Android target architectures.
  124. # NOTE: x86_64 is not ready yet, while the toolchain is in
  125. # prebuilts/ it doesn't have a sysroot which means it requires
  126. # a platform build to get Bionic and stuff.
  127. ANDROID_ARCHS="arm arm64 x86 x86_64 mips"
  128. BUILD_TYPES=
  129. for ARCH in $ANDROID_ARCHS; do
  130. BUILD_TYPES="$BUILD_TYPES android-$ARCH"
  131. done
  132. ANDROID_BUILD_TYPES=$BUILD_TYPES
  133. HOST_BUILD_TYPES="$HOST_OS-x86 $HOST_OS-generic32 $HOST_OS-generic64"
  134. HOST_BUILD_TYPES="$HOST_BUILD_TYPES $HOST_OS-x86_64"
  135. BUILD_TYPES="$ANDROID_BUILD_TYPES $HOST_BUILD_TYPES"
  136. # Parse command-line
  137. DO_HELP=
  138. SRC_DIR=$(cd $PROGDIR && pwd)
  139. OUT_DIR=out
  140. BUILD_DIR=
  141. BUILD_TYPES=
  142. NUM_JOBS=$NUM_CORES
  143. ANDROID_BUILD_TOP=$(cd $PROGDIR/../.. && pwd)
  144. for OPT; do
  145. case $OPT in
  146. --help|-h|-?)
  147. DO_HELP=true
  148. ;;
  149. --build-dir=*)
  150. BUILD_DIR=${OPT##--build-dir=}
  151. ;;
  152. --verbose)
  153. VERBOSE=$(( $VERBOSE + 1 ))
  154. ;;
  155. --jobs=*)
  156. NUM_JOBS=${OPT##--jobs=}
  157. ;;
  158. --quiet)
  159. VERBOSE=$(( $VERBOSE - 1 ))
  160. ;;
  161. -j*)
  162. NUM_JOBS=${OPT##-j}
  163. ;;
  164. -*)
  165. panic "Unknown option '$OPT', see --help for details."
  166. ;;
  167. *)
  168. BUILD_TYPES="$BUILD_TYPES $OPT"
  169. ;;
  170. esac
  171. done
  172. # Print help when needed.
  173. if [ "$DO_HELP" ]; then
  174. echo \
  175. "Usage: $PROGNAME [options] [<build-type> ...]
  176. This script is used to ensure that all OpenSSL build variants compile
  177. properly. It can be used after modifying external/openssl/openssl.config
  178. and re-running import_openssl.sh to check that any changes didn't break
  179. the build.
  180. A <build-type> is a description of a given build of the library and its
  181. program. Its format is:
  182. <compiler>-<system>-<arch>
  183. Where: <compiler> is either 'gcc' or 'clang'.
  184. <system> is 'android', 'linux' or 'darwin'.
  185. <arch> is 'arm', 'x86' or 'mips'.
  186. By default, it rebuilds the sources for the following build types:
  187. "
  188. for BUILD_TYPE in $BUILD_TYPES; do
  189. echo " $BUILD_TYPE"
  190. done
  191. echo \
  192. "However, you can pass custom values on the command-line instead.
  193. This scripts generates a custom Makefile in a temporary directory, then
  194. launches 'make' in it to build all binaries in parallel. In case of
  195. problem, you can use the --build-dir=<path> option to specify a custom
  196. build-directory, which will _not_ be removed when the script exits.
  197. For example, to better see why a build fails:
  198. ./$PROGNAME --build-dir=/tmp/mydir
  199. make -C /tmp/mydir V=1
  200. Valid options:
  201. --help|-h|-? Print this message.
  202. --build-dir=<path> Specify build directory.
  203. --jobs=<count> Run <count> parallel build jobs [$NUM_JOBS].
  204. -j<count> Same as --jobs=<count>.
  205. --verbose Increase verbosity.
  206. --quiet Decrease verbosity.
  207. "
  208. exit 0
  209. fi
  210. log "Host OS: $HOST_OS"
  211. log "Host arch: $HOST_ARCH"
  212. log "Host CPU count: $NUM_CORES"
  213. if [ -z "$BUILD_TYPES" ]; then
  214. BUILD_TYPES="$ANDROID_BUILD_TYPES $HOST_BUILD_TYPES"
  215. fi
  216. log "Build types: $BUILD_TYPES"
  217. if [ -z "$BUILD_DIR" ]; then
  218. # Create a temporary directory, ensure it gets destroyed properly
  219. # when the script exits.
  220. BUILD_DIR=$(mktemp -d)
  221. clean_build_dir () {
  222. log "Cleaning up temporary directory: $BUILD_DIR"
  223. rm -rf "$BUILD_DIR"
  224. exit $1
  225. }
  226. trap "clean_build_dir 0" EXIT
  227. trap "clean_build_dir \$?" INT HUP QUIT TERM
  228. log "Using temporary build directory: $BUILD_DIR"
  229. else
  230. log "Using user build directory: $BUILD_DIR"
  231. fi
  232. mkdir -p "$BUILD_DIR" && rm -rf "$BUILD_DIR"/*
  233. MAKEFILE=$BUILD_DIR/GNUmakefile
  234. # Return source files for a given module and architecture.
  235. # $1: module prefix (e.g. CRYPTO)
  236. # $2: build arch.
  237. get_module_src_files_for_arch () {
  238. local prefix=$1
  239. local arch=$2
  240. local src_files="$(var_value OPENSSL_${prefix}_SOURCES)"
  241. src_files="$src_files $(var_value OPENSSL_${prefix}_SOURCES_${arch})"
  242. local exclude_files="$(var_value OPENSSL_${prefix}_SOURCES_EXCLUDES_${arch})"
  243. src_files=$(filter_out "$src_files" "$exclude_files")
  244. echo "$src_files"
  245. }
  246. # Return the compiler defines for a given module and architecture
  247. # $1: module prefix (e.g. CRYPTO)
  248. # $2 build arch.
  249. get_module_defines_for_arch () {
  250. local prefix=$1
  251. local arch=$2
  252. local defines="$(var_value OPENSSL_${prefix}_DEFINES)"
  253. defines="$defines $(var_value OPENSSL_${prefix}_DEFINES_${arch})"
  254. echo "$defines"
  255. }
  256. # $1: module prefix (e.g. CRYPTO)
  257. get_module_c_includes () {
  258. var_value OPENSSL_$1_INCLUDES
  259. }
  260. # $1: build type (e.g. gcc-android-arm)
  261. # Out: build arch.
  262. get_build_arch () {
  263. echo "$1" | cut -d- -f3
  264. }
  265. # $1: build arch
  266. # Out: GNU configuration target (e.g. arm-linux-androideabi)
  267. get_build_arch_target () {
  268. case $1 in
  269. arm64)
  270. echo "aarch64-linux-android"
  271. ;;
  272. arm)
  273. echo "arm-linux-androideabi"
  274. ;;
  275. x86)
  276. echo "x86_64-linux-android"
  277. ;;
  278. x86_64)
  279. echo "x86_64-linux-android"
  280. ;;
  281. mips)
  282. echo "mipsel-linux-android"
  283. ;;
  284. *)
  285. echo "$1-linux-android"
  286. ;;
  287. esac
  288. }
  289. GCC_VERSION=4.8
  290. CLANG_VERSION=3.2
  291. get_prebuilt_gcc_dir_for_arch () {
  292. local arch=$1
  293. local target=$(get_build_arch_target $arch)
  294. # Adjust $arch for x86_64 because the prebuilts are actually
  295. # under prebuilts/gcc/<host>/x86/
  296. case $arch in
  297. x86_64)
  298. arch=x86
  299. ;;
  300. arm64)
  301. arch=aarch64
  302. ;;
  303. esac
  304. echo "$ANDROID_BUILD_TOP/prebuilts/gcc/$ANDROID_HOST_TAG/$arch/$target-$GCC_VERSION"
  305. }
  306. get_prebuilt_clang () {
  307. echo "$ANDROID_BUILD_TOP/prebuilts/clang/$ANDROID_HOST_TAG/$CLANG_VERSION/clang"
  308. }
  309. get_prebuilt_ndk_sysroot_for_arch () {
  310. echo "$ANDROID_BUILD_TOP/prebuilts/ndk/current/platforms/android-9/arch-$1"
  311. }
  312. get_c_runtime_file () {
  313. local build_type=$1
  314. local arch=$(get_build_arch $build_type)
  315. local filename=$2
  316. echo "$(get_prebuilt_ndk_sysroot_for_arch $arch)/usr/lib/$filename"
  317. }
  318. # $1: build type (e.g. gcc-android-arm)
  319. get_build_compiler () {
  320. local arch=$(get_build_arch $1)
  321. local target=$(get_build_arch_target $arch)
  322. local gcc_dir=$(get_prebuilt_gcc_dir_for_arch $arch);
  323. local result
  324. # Get the toolchain binary.
  325. case $1 in
  326. gcc-android-*)
  327. result="$gcc_dir/bin/$target-gcc"
  328. ;;
  329. clang-android-*)
  330. result="$(get_prebuilt_clang) -target $target -B$gcc_dir/$target/bin -I$gcc_dir/lib/gcc/$target/$GCC_VERSION/include"
  331. ;;
  332. gcc-*)
  333. result=gcc
  334. ;;
  335. clang-*) # Must have host clang compiler.
  336. result=clang
  337. ;;
  338. esac
  339. compiler_check=$(which $result 2>/dev/null || echo "")
  340. if [ -z "$compiler_check" ]; then
  341. panic "Could not find compiler: $result"
  342. fi
  343. # Get the Android sysroot if needed.
  344. case $1 in
  345. *-android-*)
  346. result="$result --sysroot=$(get_prebuilt_ndk_sysroot_for_arch $arch)"
  347. ;;
  348. esac
  349. # Force -m32 flag when needed for 32-bit builds.
  350. case $1 in
  351. *-x86|*-generic32)
  352. result="$result -m32"
  353. ;;
  354. esac
  355. echo "$result"
  356. }
  357. # $1: build type.
  358. # Out: common compiler flags for this build.
  359. get_build_c_flags () {
  360. local result="-O2 -fPIC"
  361. case $1 in
  362. *-android-arm)
  363. result="$result -march=armv7-a -mfpu=vfpv3-d16"
  364. ;;
  365. esac
  366. case $1 in
  367. *-generic32|*-generic64)
  368. # Generic builds do not compile without this flag.
  369. result="$result -DOPENSSL_NO_ASM"
  370. ;;
  371. esac
  372. echo "$result"
  373. }
  374. # $1: build type.
  375. # Out: linker for this build.
  376. get_build_linker () {
  377. get_build_compiler $1
  378. }
  379. clear_sources () {
  380. g_all_objs=""
  381. }
  382. # Generate build instructions to compile source files.
  383. # Also update g_all_objs.
  384. # $1: module prefix (e.g. CRYPTO)
  385. # $2: build type
  386. build_sources () {
  387. local prefix=$1
  388. local build_type=$2
  389. echo "## build_sources prefix='$prefix' build_type='$build_type'"
  390. local arch=$(get_build_arch $build_type)
  391. local src_files=$(get_module_src_files_for_arch $prefix $arch)
  392. local c_defines=$(get_module_defines_for_arch $prefix $arch)
  393. local c_includes=$(get_module_c_includes $prefix "$SRC_DIR")
  394. local build_cc=$(get_build_compiler $build_type)
  395. local build_cflags=$(get_build_c_flags $build_type)
  396. local build_linker=$(get_build_linker $build_type)
  397. local src obj def inc
  398. printf "OUT_DIR := $OUT_DIR/$build_type\n\n"
  399. printf "BUILD_CC := $build_cc\n\n"
  400. printf "BUILD_LINKER := $build_linker\n\n"
  401. printf "BUILD_CFLAGS := $build_cflags"
  402. for inc in $c_includes; do
  403. printf " -I\$(SRC_DIR)/$inc"
  404. done
  405. for def in $c_defines; do
  406. printf " -D$def"
  407. done
  408. printf "\n\n"
  409. printf "BUILD_OBJECTS :=\n\n"
  410. case $build_type in
  411. clang-android-*)
  412. # The version of clang that comes with the platform build doesn't
  413. # support simple linking of shared libraries and executables. One
  414. # has to provide the C runtime files explicitely.
  415. local crtbegin_so=$(get_c_runtime_file $build_type crtbegin_so.o)
  416. local crtend_so=$(get_c_runtime_file $build_type crtend_so.o)
  417. local crtbegin_exe=$(get_c_runtime_file $build_type crtbegin_dynamic.o)
  418. local crtend_exe=$(get_c_runtime_file $build_type crtend_android.o)
  419. printf "CRTBEGIN_SO := $crtbegin_so\n"
  420. printf "CRTEND_SO := $crtend_so\n"
  421. printf "CRTBEGIN_EXE := $crtbegin_exe\n"
  422. printf "CRTEND_EXE := $crtend_exe\n"
  423. printf "\n"
  424. ;;
  425. esac
  426. for src in $src_files; do
  427. obj=$(src_to_obj $src)
  428. g_all_objs="$g_all_objs $obj"
  429. printf "OBJ := \$(OUT_DIR)/$obj\n"
  430. printf "BUILD_OBJECTS += \$(OBJ)\n"
  431. printf "\$(OBJ): PRIVATE_CC := \$(BUILD_CC)\n"
  432. printf "\$(OBJ): PRIVATE_CFLAGS := \$(BUILD_CFLAGS)\n"
  433. printf "\$(OBJ): \$(SRC_DIR)/$src\n"
  434. printf "\t@echo [$build_type] CC $src\n"
  435. printf "\t@mkdir -p \$\$(dirname \$@)\n"
  436. printf "\t\$(hide) \$(PRIVATE_CC) \$(PRIVATE_CFLAGS) -c -o \$@ \$<\n"
  437. printf "\n"
  438. done
  439. printf "\n"
  440. }
  441. # $1: library name (e.g. crypto).
  442. # $2: module prefix (e.g. CRYPTO).
  443. # $3: build type.
  444. # $4: source directory.
  445. # $5: output directory.
  446. build_shared_library () {
  447. local name=$1
  448. local prefix=$2
  449. local build_type=$3
  450. local src_dir="$4"
  451. local out_dir="$5"
  452. local shlib="lib${name}.so"
  453. local build_linker=$(get_build_linker $build_type)
  454. clear_sources
  455. build_sources $prefix $build_type
  456. # TODO(digit): Make the clang build link properly.
  457. printf "SHLIB=\$(OUT_DIR)/$shlib\n"
  458. printf "\$(SHLIB): PRIVATE_LINKER := \$(BUILD_LINKER)\n"
  459. case $build_type in
  460. clang-android-*)
  461. printf "\$(SHLIB): PRIVATE_CRTBEGIN := \$(CRTBEGIN_SO)\n"
  462. printf "\$(SHLIB): PRIVATE_CRTEND := \$(CRTEND_SO)\n"
  463. ;;
  464. esac
  465. printf "\$(SHLIB): \$(BUILD_OBJECTS)\n"
  466. printf "\t@echo [$build_type] SHARED_LIBRARY $(basename $shlib)\n"
  467. printf "\t@mkdir -p \$\$(dirname \$@)\n"
  468. case $build_type in
  469. clang-android-*)
  470. printf "\t\$(hide) \$(PRIVATE_LINKER) -nostdlib -shared -o \$@ \$(PRIVATE_CRTBEGIN) \$^ \$(PRIVATE_CRTEND)\n"
  471. ;;
  472. *)
  473. printf "\t\$(hide) \$(PRIVATE_LINKER) -shared -o \$@ \$^\n"
  474. ;;
  475. esac
  476. printf "\n"
  477. }
  478. # $1: executable name.
  479. # $2: module prefix (e.g. APPS).
  480. # $3: build type.
  481. # $4: source directory.
  482. # $5: output directory.
  483. # $6: dependent shared libraries (e.g. 'crypto ssl')
  484. build_executable () {
  485. local name=$1
  486. local prefix=$2
  487. local build_type=$3
  488. local src_dir="$4"
  489. local out_dir="$5"
  490. local shlibs="$6"
  491. local build_linker=$(get_build_linker $build_type)
  492. clear_sources
  493. build_sources $prefix $build_type
  494. # TODO(digit): Make the clang build link properly.
  495. exec=$name
  496. all_shlibs=
  497. printf "EXEC := \$(OUT_DIR)/$name\n"
  498. printf "openssl_all: \$(EXEC)\n"
  499. printf "\$(EXEC): PRIVATE_LINKER := \$(BUILD_LINKER)\n"
  500. printf "\$(EXEC): \$(BUILD_OBJECTS)"
  501. for lib in $shlibs; do
  502. printf " \$(OUT_DIR)/lib${lib}.so"
  503. done
  504. printf "\n"
  505. printf "\t@echo [$build_type] EXECUTABLE $name\n"
  506. printf "\t@mkdir -p \$\$(dirname \$@)\n"
  507. printf "\t\$(hide) \$(PRIVATE_LINKER) -o \$@ \$^\n"
  508. printf "\n"
  509. }
  510. ALL_BUILDS=
  511. generate_openssl_build () {
  512. local build_type=$1
  513. local out="$OUT_DIR/$build_type"
  514. ALL_BUILDS="$ALL_BUILDS $build_type"
  515. echo "# Build type: $build_type"
  516. build_shared_library crypto CRYPTO $build_type "$SRC_DIR" "$out"
  517. build_shared_library ssl SSL $build_type "$SRC_DIR" "$out"
  518. build_executable openssl APPS $build_type "$SRC_DIR" "$out" "crypto ssl"
  519. }
  520. generate_makefile () {
  521. echo \
  522. "# Auto-generated by $PROGDIR - do not edit
  523. .PHONY: openssl_all
  524. all: openssl_all
  525. # Use 'make V=1' to print build commands.
  526. ifeq (1,\$(V))
  527. hide :=
  528. else
  529. hide := @
  530. endif
  531. SRC_DIR=$SRC_DIR
  532. OUT_DIR=$OUT_DIR
  533. "
  534. for BUILD_TYPE in $BUILD_TYPES; do
  535. generate_openssl_build gcc-$BUILD_TYPE
  536. done
  537. # TODO(digit): Make the Clang build run.
  538. # for BUILD_TYPE in $ANDROID_BUILD_TYPES; do
  539. # generate_openssl_build clang-$BUILD_TYPE
  540. # done
  541. }
  542. . $SRC_DIR/openssl.config
  543. dump "Generating Makefile"
  544. log "Makefile path: $MAKEFILE"
  545. generate_makefile > $MAKEFILE
  546. dump "Building libraries with $NUM_JOBS jobs"
  547. dump "For the following builds:"
  548. for BUILD in $ALL_BUILDS; do
  549. dump " $BUILD"
  550. done
  551. MAKE_FLAGS="-j$NUM_JOBS"
  552. if [ "$VERBOSE" -gt 2 ]; then
  553. MAKE_FLAGS="$MAKE_FLAGS V=1"
  554. fi
  555. run make $MAKE_FLAGS -f "$MAKEFILE" -C "$BUILD_DIR"
  556. case $? in
  557. 0)
  558. dump "All OK, congratulations!"
  559. ;;
  560. *)
  561. dump "Error, try doing the following to inspect the issues:"
  562. dump " $PROGNAME --build-dir=/tmp/mybuild"
  563. dump " make -C /tmp/mybuild V=1"
  564. dump " "
  565. ;;
  566. esac