1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
|
#!/bin/bash
set -e
# Ensure that binaries from MSYS2 are preferred over Windows-native commands like find and sort which work differently.
PATH="/usr/bin/:$PATH"
# $ANDROID_HOME can be used-defined, else the default location is used. Important notes:
# - The path must not contain spaces on Windows.
# - $HOME must be used instead of ~ else cargo-ndk cannot find the folder.
ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}"
export ANDROID_HOME
BUILD_FLAGS="${BUILD_FLAGS:--j$(nproc)}"
export BUILD_FLAGS
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
log_info() {
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "$1"
}
log_warn() {
printf "${COLOR_YELLOW}%s${COLOR_RESET}\n" "$1" 1>&2
}
log_error() {
printf "${COLOR_RED}%s${COLOR_RESET}\n" "$1" 1>&2
}
if [ -z ${1+x} ]; then
SHOW_USAGE_INFO=1
log_error "Did not pass Android build type"
else
ANDROID_BUILD=$1
if [[ "${ANDROID_BUILD}" == "x64" ]]; then
ANDROID_BUILD="x86_64"
fi
log_warn "Android build type: ${ANDROID_BUILD}"
fi
if [ -z ${2+x} ]; then
SHOW_USAGE_INFO=1
log_error "Did not pass game name"
else
GAME_NAME=$2
log_warn "Game name: ${GAME_NAME}"
fi
if [ -z ${3+x} ]; then
SHOW_USAGE_INFO=1
log_error "Did not pass package name"
else
PACKAGE_NAME=$3
log_warn "Package name: ${PACKAGE_NAME}"
fi
if [ -z ${4+x} ]; then
SHOW_USAGE_INFO=1
log_error "Did not pass build type"
else
BUILD_TYPE=$4
log_warn "Build type: ${BUILD_TYPE}"
fi
if [ -z ${5+x} ]; then
SHOW_USAGE_INFO=1
log_error "Did not pass build folder"
else
BUILD_FOLDER=$5
log_warn "Build folder: ${BUILD_FOLDER}"
fi
if [ $SHOW_USAGE_INFO == 1 ]; then
log_error "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
log_warn "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
log_warn "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
log_warn "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
log_warn "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
log_warn "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
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 \
-DANDROID_PACKAGE_NAME="${PACKAGE_NAME//./_}" \
-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=ON \
-DTOOLS=OFF \
-DDEV=TRUE \
-DCMAKE_CROSSCOMPILING=ON \
-DVULKAN=ON \
-DVIDEORECORDER=OFF
(
cd "${BUILD_FOLDER}/$ANDROID_SUB_BUILD_DIR/$1" || exit 1
# We want word splitting
# shellcheck disable=SC2086
cmake --build . --target game-client game-server $BUILD_FLAGS
)
}
mkdir -p "${BUILD_FOLDER}"
if [[ "${ANDROID_BUILD}" == "arm" || "${ANDROID_BUILD}" == "all" ]]; then
log_info "Building cmake (arm)..."
build_for_type arm armeabi-v7a armv7-linux-androideabi
fi
if [[ "${ANDROID_BUILD}" == "arm64" || "${ANDROID_BUILD}" == "all" ]]; then
log_info "Building cmake (arm64)..."
build_for_type arm64 arm64-v8a aarch64-linux-android
fi
if [[ "${ANDROID_BUILD}" == "x86" || "${ANDROID_BUILD}" == "all" ]]; then
log_info "Building cmake (x86)..."
build_for_type x86 x86 i686-linux-android
fi
if [[ "${ANDROID_BUILD}" == "x86_64" || "${ANDROID_BUILD}" == "all" ]]; then
log_info "Building cmake (x86_64)..."
build_for_type x86_64 x86_64 x86_64-linux-android
fi
log_info "Copying project files..."
cd "${BUILD_FOLDER}" || exit 1
mkdir -p src/main
mkdir -p gradle/wrapper
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/build.gradle build.gradle
copy_dummy_files scripts/android/files/gradlew gradlew
copy_dummy_files scripts/android/files/gradlew.bat gradlew.bat
copy_dummy_files scripts/android/files/gradle/wrapper/gradle-wrapper.jar gradle/wrapper/gradle-wrapper.jar
copy_dummy_files scripts/android/files/gradle/wrapper/gradle-wrapper.properties gradle/wrapper/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
rm -R -f src/main/res
cp -R ../scripts/android/files/res src/main/
mkdir -p src/main/res/mipmap
cp ../other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher.png
cp ../other/icons/DDNet_256x256x32.png src/main/res/mipmap/ic_launcher_round.png
chmod +x ./gradlew
log_info "Copying libraries..."
function copy_libs() {
mkdir -p "lib/$2"
cp "$ANDROID_SUB_BUILD_DIR/$1/libDDNet.so" "lib/$2" || exit 1
cp "$ANDROID_SUB_BUILD_DIR/$1/libDDNet-Server.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}" == "all" ]]; then
copy_libs x86_64 x86_64
fi
ANDROID_BUILD_DUMMY=$ANDROID_BUILD
if [[ "${ANDROID_BUILD}" == "all" ]]; then
ANDROID_BUILD_DUMMY=arm
fi
log_info "Copying data folder..."
mkdir -p assets/asset_integrity_files
cp -R "$ANDROID_SUB_BUILD_DIR/$ANDROID_BUILD_DUMMY/data" ./assets/asset_integrity_files
log_info "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
log_info "Creating integrity index file..."
(
cd assets/asset_integrity_files || exit 1
tmpfile="$(mktemp /tmp/hash_strings.XXX)"
find data -iname "*" -type f -print0 | xargs -0 sha256sum | awk '{gsub(/^\*/, "", $2); print substr($0, index($0, $2)), $1}' > "$tmpfile"
full_hash="$(sha256sum "$tmpfile" | cut -d' ' -f 1)"
rm -f "integrity.txt"
{
echo "$full_hash"
cat "$tmpfile"
} > "integrity.txt"
)
log_info "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 ..
|