0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-19 19:42:19 +02:00
libsignal/java/build_jni.sh

185 lines
6.5 KiB
Bash
Raw Permalink Normal View History

2020-11-04 23:37:41 +01:00
#!/bin/bash
#
# Copyright (C) 2020-2022 Signal Messenger, LLC.
# SPDX-License-Identifier: AGPL-3.0-only
#
set -euo pipefail
SCRIPT_DIR=$(dirname "$0")
cd "${SCRIPT_DIR}"/..
. bin/build_helpers.sh
# These paths are relative to the root directory
ANDROID_LIB_DIR=java/android/src/main/jniLibs
DESKTOP_LIB_DIR=java/client/src/main/resources
SERVER_LIB_DIR=java/server/src/main/resources
export CARGO_PROFILE_RELEASE_DEBUG=1 # enable line tables
export RUSTFLAGS="--cfg aes_armv8 --cfg polyval_armv8 ${RUSTFLAGS:-}" # Enable ARMv8 cryptography acceleration when available
DEBUG_LEVEL_LOGS=
while [ "${1:-}" != "" ]; do
case "${1:-}" in
--debug-level-logs )
DEBUG_LEVEL_LOGS=1
shift
;;
-* )
echo "Unrecognized flag $1; expected --debug-level-logs" >&2
exit 2
;;
*)
break
esac
done
if [[ -z "${DEBUG_LEVEL_LOGS:-}" ]]; then
FEATURES+=("log/release_max_level_info")
fi
# usage: build_desktop_for_arch target_triple host_triple output_dir
build_desktop_for_arch () {
local CC
local CXX
local CPATH
local lib_dir="${3}/"
local cpuarch="${1%%-*}"
case "$cpuarch" in
x86_64)
suffix=amd64
;;
aarch64)
suffix=aarch64
;;
*)
echo "building for unknown CPU architecture ${cpuarch}; update build_jni.sh"
exit 2
esac
if [[ "$1" != "$2" ]]; then
# Set up cross-compiling flags
if [[ "$1" == *-linux-* && "$2" == *-linux-* && -z "${CC:-}" ]]; then
# When cross-compiling *from* Linux *to* Linux,
# set up standard cross-compiling environment if not already set
echo 'setting Linux cross-compilation options...'
export "CARGO_TARGET_$(echo "$cpuarch" | tr "[:lower:]" "[:upper:]")_UNKNOWN_LINUX_GNU_LINKER"="${cpuarch}-linux-gnu-gcc"
export CC="${cpuarch}-linux-gnu-gcc"
export CXX="${cpuarch}-linux-gnu-g++"
export CPATH="/usr/${cpuarch}-linux-gnu/include"
fi
fi
echo_then_run cargo build -p libsignal-jni -p libsignal-jni-testing --release ${FEATURES:+--features "${FEATURES[*]}"} --target "$1"
copy_built_library "target/${1}/release" signal_jni "$lib_dir" "signal_jni_${suffix}"
copy_built_library "target/${1}/release" signal_jni_testing "$lib_dir" "signal_jni_testing_${suffix}"
}
android_abis=()
while [ "${1:-}" != "" ]; do
case "${1:-}" in
desktop | server | server-all )
if [[ "$1" == desktop ]]; then
lib_dir=$DESKTOP_LIB_DIR
else
lib_dir=$SERVER_LIB_DIR
fi
# On Linux, cdylibs don't include public symbols from their dependencies,
# even if those symbols have been re-exported in the Rust source.
# Using LTO works around this at the cost of a slightly slower build.
# https://github.com/rust-lang/rfcs/issues/2771
export CARGO_PROFILE_RELEASE_LTO=thin
host_triple=$(rustc -vV | sed -n 's|host: ||p')
if [[ "$1" == "server-all" ]]; then
build_desktop_for_arch x86_64-unknown-linux-gnu "$host_triple" $lib_dir
# Enable ARMv8.2 extensions for a production aarch64 server build
RUSTFLAGS="-C target-feature=+v8.2a ${RUSTFLAGS:-}" \
build_desktop_for_arch aarch64-unknown-linux-gnu "$host_triple" $lib_dir
else
build_desktop_for_arch "${CARGO_BUILD_TARGET:-$host_triple}" "$host_triple" $lib_dir
fi
exit
;;
android )
android_abis+=(arm64-v8a armeabi-v7a x86_64 x86)
;;
android-arm64 | android-aarch64 )
android_abis+=(arm64-v8a)
;;
android-arm | android-armv7 )
android_abis+=(armeabi-v7a)
;;
android-x86_64 )
android_abis+=(x86_64)
;;
android-x86 | android-i686 )
android_abis+=(x86)
;;
*)
echo "Unknown target '${1:-}' (use 'desktop', 'android', or 'android-\$ARCH')" >&2
exit 2
;;
esac
shift
done
if (( ${#android_abis[@]} == 0 )); then
echo "Missing target (use 'desktop', 'android', or 'android-\$ARCH')" >&2
exit 2
fi
# Everything from here down is Android-only.
export CARGO_PROFILE_RELEASE_OPT_LEVEL=s # optimize for size over speed
# Use full LTO and small BoringSSL curve tables to reduce binary size.
export CFLAGS="-DOPENSSL_SMALL -flto=full ${CFLAGS:-}"
export CARGO_PROFILE_RELEASE_LTO=fat
export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1
# Use the Android NDK's prebuilt Clang+lld as pqcrypto's compiler and Rust's linker.
ANDROID_TOOLCHAIN_DIR=$(echo "${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt"/*/bin/)
export CC_aarch64_linux_android="${ANDROID_TOOLCHAIN_DIR}/aarch64-linux-android21-clang"
export CC_armv7_linux_androideabi="${ANDROID_TOOLCHAIN_DIR}/armv7a-linux-androideabi21-clang"
export CC_x86_64_linux_android="${ANDROID_TOOLCHAIN_DIR}/x86_64-linux-android21-clang"
export CC_i686_linux_android="${ANDROID_TOOLCHAIN_DIR}/i686-linux-android21-clang"
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${CC_aarch64_linux_android}"
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${CC_armv7_linux_androideabi}"
export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="${CC_x86_64_linux_android}"
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="${CC_i686_linux_android}"
export TARGET_AR="${ANDROID_TOOLCHAIN_DIR}/llvm-ar"
# The 64-bit curve25519-dalek backend is faster than the 32-bit one on at least some armv7a phones.
# Comment out the following to allow the 32-bit backend on 32-bit targets.
export RUSTFLAGS="--cfg curve25519_dalek_bits=\"64\" ${RUSTFLAGS:-}"
target_for_abi() {
case "$1" in
arm64-v8a)
echo aarch64-linux-android
;;
armeabi-v7a)
echo armv7-linux-androideabi
;;
x86_64)
echo x86_64-linux-android
;;
x86)
echo i686-linux-android
;;
*)
echo "Unknown Android ABI $1; please update build_jni.sh" >&2
exit 2
;;
esac
}
for abi in "${android_abis[@]}"; do
rust_target=$(target_for_abi "$abi")
echo_then_run cargo build -p libsignal-jni -p libsignal-jni-testing --release ${FEATURES:+--features "${FEATURES[*]}"} -Z unstable-options --target "$rust_target" --out-dir "${ANDROID_LIB_DIR}/$abi"
done