mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 21:48:19 +00:00
d536bceed6
The minimum supported API version must be specified when building the native libraries, otherwise this may cause linking errors when launching the app. The minimum API level is increased to 24 (Android 7.0, covering 97.2% of usages) because: - Vulkan is only available from API 24+ on ARM64 and x64. - curl only compiles with API 23+. - The NDK version we use supports only API 21+. Ensure that the C++/Linker flags are set when building Android libraries, which was causing errors due to `-fPIC` not being set for all libraries.
287 lines
9 KiB
Bash
Executable file
287 lines
9 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# $HOME must be used instead of ~ else cargo-ndk cannot find the folder
|
|
export ANDROID_HOME=$HOME/Android/Sdk
|
|
MAKEFLAGS=-j$(nproc)
|
|
export MAKEFLAGS
|
|
|
|
ANDROID_NDK_VERSION="$(cd "$ANDROID_HOME/ndk" && find . -maxdepth 1 | sort -n | tail -1)"
|
|
ANDROID_NDK_VERSION="${ANDROID_NDK_VERSION:2}"
|
|
# ANDROID_NDK_HOME must be exported for cargo-ndk
|
|
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION"
|
|
|
|
# ANDROID_API_LEVEL must specify the _minimum_ supported SDK version, otherwise this will cause linking errors at launch
|
|
ANDROID_API_LEVEL=24
|
|
ANDROID_SUB_BUILD_DIR=build_arch
|
|
|
|
COLOR_RED="\e[1;31m"
|
|
COLOR_YELLOW="\e[1;33m"
|
|
COLOR_CYAN="\e[1;36m"
|
|
COLOR_RESET="\e[0m"
|
|
|
|
SHOW_USAGE_INFO=0
|
|
|
|
if [ -z ${1+x} ]; then
|
|
SHOW_USAGE_INFO=1
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Did not pass Android build type"
|
|
else
|
|
ANDROID_BUILD=$1
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Android build type: ${ANDROID_BUILD}"
|
|
fi
|
|
|
|
if [ -z ${2+x} ]; then
|
|
SHOW_USAGE_INFO=1
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Did not pass game name"
|
|
else
|
|
GAME_NAME=$2
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Game name: ${GAME_NAME}"
|
|
fi
|
|
|
|
if [ -z ${3+x} ]; then
|
|
SHOW_USAGE_INFO=1
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Did not pass package name"
|
|
else
|
|
PACKAGE_NAME=$3
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Package name: ${PACKAGE_NAME}"
|
|
fi
|
|
|
|
if [ -z ${4+x} ]; then
|
|
SHOW_USAGE_INFO=1
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Did not pass build type"
|
|
else
|
|
BUILD_TYPE=$4
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Build type: ${BUILD_TYPE}"
|
|
fi
|
|
|
|
if [ -z ${5+x} ]; then
|
|
SHOW_USAGE_INFO=1
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Did not pass build folder"
|
|
else
|
|
BUILD_FOLDER=$5
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Build folder: ${BUILD_FOLDER}"
|
|
fi
|
|
|
|
if [ $SHOW_USAGE_INFO == 1 ]; then
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Usage: ./cmake_android.sh <x86/x86_64/arm/arm64/all> <Game name> <Package name> <Debug/Release> <Build folder>"
|
|
exit 1
|
|
fi
|
|
|
|
# These are the properties of the default Android debug key. The debug key will
|
|
# automatically be created during the Gradle build if it does not exist already,
|
|
# so you don't need to create it yourself.
|
|
DEFAULT_KEY_NAME=~/.android/debug.keystore
|
|
DEFAULT_KEY_PW=android
|
|
DEFAULT_KEY_ALIAS=androiddebugkey
|
|
|
|
if [ -z ${TW_KEY_NAME+x} ]; then
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Did not pass a key path for the APK signer, using default: ${DEFAULT_KEY_NAME}"
|
|
else
|
|
DEFAULT_KEY_NAME=$TW_KEY_NAME
|
|
fi
|
|
if [ -z ${TW_KEY_PW+x} ]; then
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Did not pass a key password for the APK signer, using default: ${DEFAULT_KEY_PW}"
|
|
else
|
|
DEFAULT_KEY_PW=$TW_KEY_PW
|
|
fi
|
|
if [ -z ${TW_KEY_ALIAS+x} ]; then
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Did not pass a key alias for the APK signer, using default: ${DEFAULT_KEY_ALIAS}"
|
|
else
|
|
DEFAULT_KEY_ALIAS=$TW_KEY_ALIAS
|
|
fi
|
|
|
|
export TW_KEY_NAME="${DEFAULT_KEY_NAME}"
|
|
export TW_KEY_PW=$DEFAULT_KEY_PW
|
|
export TW_KEY_ALIAS=$DEFAULT_KEY_ALIAS
|
|
|
|
ANDROID_VERSION_CODE=1
|
|
if [ -z ${TW_VERSION_CODE+x} ]; then
|
|
ANDROID_VERSION_CODE=$(grep '#define DDNET_VERSION_NUMBER' src/game/version.h | awk '{print $3}')
|
|
if [ -z ${ANDROID_VERSION_CODE+x} ]; then
|
|
ANDROID_VERSION_CODE=1
|
|
fi
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Did not pass a version code, using default: ${ANDROID_VERSION_CODE}"
|
|
else
|
|
ANDROID_VERSION_CODE=$TW_VERSION_CODE
|
|
fi
|
|
|
|
export TW_VERSION_CODE=$ANDROID_VERSION_CODE
|
|
|
|
ANDROID_VERSION_NAME="1.0"
|
|
if [ -z ${TW_VERSION_NAME+x} ]; then
|
|
ANDROID_VERSION_NAME="$(grep '#define GAME_RELEASE_VERSION' src/game/version.h | awk '{print $3}' | tr -d '"')"
|
|
if [ -z ${ANDROID_VERSION_NAME+x} ]; then
|
|
ANDROID_VERSION_NAME="1.0"
|
|
fi
|
|
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "Did not pass a version name, using default: ${ANDROID_VERSION_NAME}"
|
|
else
|
|
ANDROID_VERSION_NAME=$TW_VERSION_NAME
|
|
fi
|
|
|
|
export TW_VERSION_NAME=$ANDROID_VERSION_NAME
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake..."
|
|
|
|
function build_for_type() {
|
|
cmake \
|
|
-H. \
|
|
-G "Ninja" \
|
|
-DPREFER_BUNDLED_LIBS=ON \
|
|
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
|
-DANDROID_PLATFORM="android-${ANDROID_API_LEVEL}" \
|
|
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
|
|
-DANDROID_NDK="$ANDROID_NDK_HOME" \
|
|
-DANDROID_ABI="${2}" \
|
|
-DANDROID_ARM_NEON=TRUE \
|
|
-DCMAKE_ANDROID_NDK="$ANDROID_NDK_HOME" \
|
|
-DCMAKE_SYSTEM_NAME=Android \
|
|
-DCMAKE_SYSTEM_VERSION="$ANDROID_API_LEVEL" \
|
|
-DCMAKE_ANDROID_ARCH_ABI="${2}" \
|
|
-DCARGO_NDK_TARGET="${3}" \
|
|
-DCARGO_NDK_API="$ANDROID_API_LEVEL" \
|
|
-B"${BUILD_FOLDER}/$ANDROID_SUB_BUILD_DIR/$1" \
|
|
-DSERVER=OFF \
|
|
-DTOOLS=OFF \
|
|
-DDEV=TRUE \
|
|
-DCMAKE_CROSSCOMPILING=ON \
|
|
-DVULKAN=ON \
|
|
-DVIDEORECORDER=OFF
|
|
(
|
|
cd "${BUILD_FOLDER}/$ANDROID_SUB_BUILD_DIR/$1" || exit 1
|
|
cmake --build . --target game-client
|
|
)
|
|
}
|
|
|
|
mkdir -p "${BUILD_FOLDER}"
|
|
|
|
if [[ "${ANDROID_BUILD}" == "arm" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
build_for_type arm armeabi-v7a armv7-linux-androideabi &
|
|
PID_BUILD_ARM=$!
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "arm64" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
build_for_type arm64 arm64-v8a aarch64-linux-android &
|
|
PID_BUILD_ARM64=$!
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "x86" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
build_for_type x86 x86 i686-linux-android &
|
|
PID_BUILD_X86=$!
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "x86_64" || "${ANDROID_BUILD}" == "x64" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
build_for_type x86_64 x86_64 x86_64-linux-android &
|
|
PID_BUILD_X86_64=$!
|
|
fi
|
|
|
|
if [ -n "$PID_BUILD_ARM" ] && ! wait "$PID_BUILD_ARM"; then
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Building for arm failed"
|
|
exit 1
|
|
fi
|
|
if [ -n "$PID_BUILD_ARM64" ] && ! wait "$PID_BUILD_ARM64"; then
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Building for arm64 failed"
|
|
exit 1
|
|
fi
|
|
if [ -n "$PID_BUILD_X86" ] && ! wait "$PID_BUILD_X86"; then
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Building for x86 failed"
|
|
exit 1
|
|
fi
|
|
if [ -n "$PID_BUILD_X86_64" ] && ! wait "$PID_BUILD_X86_64"; then
|
|
printf "${COLOR_RED}%s${COLOR_RESET}\n" "Building for x86_64 failed"
|
|
exit 1
|
|
fi
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Copying project files..."
|
|
|
|
cd "${BUILD_FOLDER}" || exit 1
|
|
|
|
mkdir -p src/main
|
|
mkdir -p src/main/res/values
|
|
mkdir -p src/main/res/xml
|
|
mkdir -p src/main/res/mipmap
|
|
|
|
function copy_dummy_files() {
|
|
rm -f ./"$2"
|
|
cp ../"$1" "$2"
|
|
}
|
|
|
|
copy_dummy_files scripts/android/files/build.sh build.sh
|
|
copy_dummy_files scripts/android/files/gradle-wrapper.jar gradle-wrapper.jar
|
|
copy_dummy_files scripts/android/files/build.gradle build.gradle
|
|
copy_dummy_files scripts/android/files/gradle-wrapper.properties gradle-wrapper.properties
|
|
copy_dummy_files scripts/android/files/gradle.properties gradle.properties
|
|
copy_dummy_files scripts/android/files/proguard-rules.pro proguard-rules.pro
|
|
copy_dummy_files scripts/android/files/settings.gradle settings.gradle
|
|
copy_dummy_files scripts/android/files/AndroidManifest.xml src/main/AndroidManifest.xml
|
|
copy_dummy_files scripts/android/files/res/values/strings.xml src/main/res/values/strings.xml
|
|
copy_dummy_files scripts/android/files/res/xml/shortcuts.xml src/main/res/xml/shortcuts.xml
|
|
copy_dummy_files other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher.png
|
|
copy_dummy_files other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher_round.png
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Copying libraries..."
|
|
|
|
function copy_libs() {
|
|
mkdir -p "lib/$2"
|
|
cp "$ANDROID_SUB_BUILD_DIR/$1/libDDNet.so" "lib/$2" || exit 1
|
|
}
|
|
|
|
if [[ "${ANDROID_BUILD}" == "arm" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
copy_libs arm armeabi-v7a
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "arm64" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
copy_libs arm64 arm64-v8a
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "x86" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
copy_libs x86 x86
|
|
fi
|
|
|
|
if [[ "${ANDROID_BUILD}" == "x86_64" || "${ANDROID_BUILD}" == "x64" || "${ANDROID_BUILD}" == "all" ]]; then
|
|
copy_libs x86_64 x86_64
|
|
fi
|
|
|
|
ANDROID_BUILD_DUMMY=$ANDROID_BUILD
|
|
if [[ "${ANDROID_BUILD}" == "all" ]]; then
|
|
ANDROID_BUILD_DUMMY=arm
|
|
fi
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Copying data folder..."
|
|
mkdir -p assets/asset_integrity_files
|
|
cp -R "$ANDROID_SUB_BUILD_DIR/$ANDROID_BUILD_DUMMY/data" ./assets/asset_integrity_files
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Downloading certificate..."
|
|
curl -s -S --remote-name --time-cond cacert.pem https://curl.se/ca/cacert.pem
|
|
cp ./cacert.pem ./assets/asset_integrity_files/data/cacert.pem || exit 1
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Creating integrity index file..."
|
|
(
|
|
cd assets/asset_integrity_files || exit 1
|
|
|
|
tmpfile="$(mktemp /tmp/hash_strings.XXX)"
|
|
|
|
find data -iname "*" -type f -print0 | while IFS= read -r -d $'\0' file; do
|
|
sha_hash=$(sha256sum "$file" | cut -d' ' -f 1)
|
|
echo "$file $sha_hash" >> "$tmpfile"
|
|
done
|
|
|
|
full_hash="$(sha256sum "$tmpfile" | cut -d' ' -f 1)"
|
|
|
|
rm -f "integrity.txt"
|
|
{
|
|
echo "$full_hash"
|
|
cat "$tmpfile"
|
|
} > "integrity.txt"
|
|
)
|
|
|
|
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Preparing gradle build..."
|
|
|
|
rm -R -f src/main/java/org
|
|
mkdir -p src/main/java
|
|
cp -R ../scripts/android/files/java/org src/main/java/
|
|
cp -R ../ddnet-libs/sdl/java/org src/main/java/
|
|
|
|
# shellcheck disable=SC1091
|
|
source ./build.sh "$GAME_NAME" "$PACKAGE_NAME" "$BUILD_TYPE"
|
|
|
|
cd ..
|