From b2b0cd0c81358c8dbe9ae5400c2b67ff97e0fc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 13:30:27 +0200 Subject: [PATCH 01/13] Fix shadowed variable declarations in `android_main.cpp` --- src/android/android_main.cpp | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/android/android_main.cpp b/src/android/android_main.cpp index 03b06beec..1339fe1eb 100644 --- a/src/android/android_main.cpp +++ b/src/android/android_main.cpp @@ -54,23 +54,23 @@ void InitAndroid() dbg_msg("integrity", "copying integrity.txt with size: %ld", length); - IOHANDLE pIO = io_open("integrity.txt", IOFLAG_WRITE); - io_write(pIO, pAl, length); - io_close(pIO); + IOHANDLE IntegrityFileWrite = io_open("integrity.txt", IOFLAG_WRITE); + io_write(IntegrityFileWrite, pAl, length); + io_close(IntegrityFileWrite); free(pAl); } - IOHANDLE pIO = io_open("integrity.txt", IOFLAG_READ); - CLineReader LineReader; - LineReader.Init(pIO); + IOHANDLE IntegrityFileRead = io_open("integrity.txt", IOFLAG_READ); + CLineReader IntegrityFileLineReader; + IntegrityFileLineReader.Init(IntegrityFileRead); const char *pReadLine = NULL; std::vector vLines; - while((pReadLine = LineReader.Get())) + while((pReadLine = IntegrityFileLineReader.Get())) { vLines.push_back(pReadLine); } - io_close(pIO); + io_close(IntegrityFileRead); // first line is the whole hash std::string AllAsOne; @@ -82,12 +82,12 @@ void InitAndroid() SHA256_DIGEST ShaAll; bool GotSHA = false; { - IOHANDLE pIOR = io_open("integrity_save.txt", IOFLAG_READ); - if(pIOR != NULL) + IOHANDLE IntegritySaveFileRead = io_open("integrity_save.txt", IOFLAG_READ); + if(IntegritySaveFileRead != NULL) { - CLineReader LineReader; - LineReader.Init(pIOR); - const char *pLine = LineReader.Get(); + CLineReader IntegritySaveLineReader; + IntegritySaveLineReader.Init(IntegritySaveFileRead); + const char *pLine = IntegritySaveLineReader.Get(); if(pLine != NULL) { sha256_from_str(&ShaAll, pLine); @@ -138,20 +138,20 @@ void InitAndroid() SDL_RWclose(pF); - IOHANDLE pIO = io_open(FileName.c_str(), IOFLAG_WRITE); - io_write(pIO, pAl, length); - io_close(pIO); + IOHANDLE AssetFileWrite = io_open(FileName.c_str(), IOFLAG_WRITE); + io_write(AssetFileWrite, pAl, length); + io_close(AssetFileWrite); free(pAl); } - IOHANDLE pIOR = io_open("integrity_save.txt", IOFLAG_WRITE); - if(pIOR != NULL) + IOHANDLE IntegritySaveFileWrite = io_open("integrity_save.txt", IOFLAG_WRITE); + if(IntegritySaveFileWrite != NULL) { char aFileSHA[SHA256_MAXSTRSIZE]; sha256_str(ShaAllFile, aFileSHA, sizeof(aFileSHA)); - io_write(pIOR, aFileSHA, str_length(aFileSHA)); - io_close(pIOR); + io_write(IntegritySaveFileWrite, aFileSHA, str_length(aFileSHA)); + io_close(IntegritySaveFileWrite); } } } From 4a2a23530cede286534bfa1aedae212fa8330ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 8 May 2024 22:52:16 +0200 Subject: [PATCH 02/13] Fix `integrity_save.txt` file not being closed --- src/android/android_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/android_main.cpp b/src/android/android_main.cpp index 1339fe1eb..0668b30dd 100644 --- a/src/android/android_main.cpp +++ b/src/android/android_main.cpp @@ -93,6 +93,7 @@ void InitAndroid() sha256_from_str(&ShaAll, pLine); GotSHA = true; } + io_close(IntegritySaveFileRead); } } From dfae99da76ec1aaedb7d0c3a859e2488825e75d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 21:06:11 +0200 Subject: [PATCH 03/13] Fix unused variable `Silent` in `client.cpp` on Android --- src/engine/client/client.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 946970efc..3ff8018e3 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -4262,16 +4262,6 @@ int main(int argc, const char **argv) #endif CCmdlineFix CmdlineFix(&argc, &argv); - bool Silent = false; - - for(int i = 1; i < argc; i++) - { - if(str_comp("-s", argv[i]) == 0 || str_comp("--silent", argv[i]) == 0) - { - Silent = true; - } - } - #if defined(CONF_PLATFORM_ANDROID) InitAndroid(); #endif @@ -4285,6 +4275,14 @@ int main(int argc, const char **argv) #if defined(CONF_PLATFORM_ANDROID) pStdoutLogger = std::shared_ptr(log_logger_android()); #else + bool Silent = false; + for(int i = 1; i < argc; i++) + { + if(str_comp("-s", argv[i]) == 0 || str_comp("--silent", argv[i]) == 0) + { + Silent = true; + } + } if(!Silent) { pStdoutLogger = std::shared_ptr(log_logger_stdout()); From ad9b44bfed22f6651c63e2c168ae6027f0307c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 8 May 2024 12:49:14 +0200 Subject: [PATCH 04/13] Remove `local.properties` and add it to `.gitignore` This file is not supposed to be added to version control and will be regenerated whenever the Gradle build is run. --- .gitignore | 3 +++ scripts/android/cmake_android.sh | 1 - scripts/android/files/build.sh | 3 --- scripts/android/files/local.properties | 10 ---------- 4 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 scripts/android/files/local.properties diff --git a/.gitignore b/.gitignore index fc39ec3d7..3c8434084 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,9 @@ testrunner\[1\]_include.cmake /SDL2.framework +# Android +local.properties + # Ignore all the generated executables without extensions (for non-Windows # systems). DDNet diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index 9f0b242e1..7073a57d6 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -154,7 +154,6 @@ 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/local.properties local.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 diff --git a/scripts/android/files/build.sh b/scripts/android/files/build.sh index 1086dacf6..d61843695 100644 --- a/scripts/android/files/build.sh +++ b/scripts/android/files/build.sh @@ -36,9 +36,6 @@ sed -i "s/DDNet/${2}/g" src/main/res/values/strings.xml sed -i "s/\"DDNet\"/\"${2}\"/g" src/main/AndroidManifest.xml sed -i "s/tw.DDNet/${_REPLACE_PACKAGE_NAME_STR}/g" src/main/AndroidManifest.xml -__TW_HOME_DIR=$(echo "$HOME"|sed 's/\//\\\//g') - -sed -i "s/TW_HOME_DIR/${__TW_HOME_DIR}/g" local.properties sed -i "s/TW_NDK_VERSION/${ANDROID_NDK_VERSION}/g" build.gradle sed -i "s/TW_VERSION_CODE/${TW_VERSION_CODE}/g" build.gradle sed -i "s/TW_VERSION_NAME/${TW_VERSION_NAME}/g" build.gradle diff --git a/scripts/android/files/local.properties b/scripts/android/files/local.properties deleted file mode 100644 index 73c3a2107..000000000 --- a/scripts/android/files/local.properties +++ /dev/null @@ -1,10 +0,0 @@ -## This file is automatically generated by Android Studio. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file should *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -sdk.dir="TW_HOME_DIR/Android/Sdk" From 9afe7444c1172cad079eabd8fcc327c0584b2b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 13:12:48 +0200 Subject: [PATCH 05/13] Fix SDL3 being used in `gen_libs.sh` The SDL default branch is now SDL3, so we need to check out specifically the SDL2 branch. --- scripts/compile_libs/gen_libs.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/compile_libs/gen_libs.sh b/scripts/compile_libs/gen_libs.sh index e41bdf53a..7d144585a 100755 --- a/scripts/compile_libs/gen_libs.sh +++ b/scripts/compile_libs/gen_libs.sh @@ -55,7 +55,11 @@ cd "$1" || exit 1 function build_cmake_lib() { if [ ! -d "${1}" ]; then - git clone "${2}" "${1}" + if [ -z ${3+x} ]; then + git clone "${2}" "${1}" + else + git clone --single-branch --branch "${3}" "${2}" "${1}" + fi fi ( cd "${1}" || exit 1 @@ -90,7 +94,7 @@ build_cmake_lib zlib https://github.com/madler/zlib build_cmake_lib png https://github.com/glennrp/libpng build_cmake_lib curl https://github.com/curl/curl build_cmake_lib freetype2 https://gitlab.freedesktop.org/freetype/freetype -build_cmake_lib sdl https://github.com/libsdl-org/SDL +build_cmake_lib sdl https://github.com/libsdl-org/SDL SDL2 build_cmake_lib ogg https://github.com/xiph/ogg build_cmake_lib opus https://github.com/xiph/opus From 468cd858395496dcee12ec068580d34fc91a5ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 13:13:34 +0200 Subject: [PATCH 06/13] Add build folder parameter to `cmake_android.sh` Add a parameter instead of using the fixed build folder `build_android`. --- scripts/android/cmake_android.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index 7073a57d6..6897a414c 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -11,6 +11,7 @@ ANDROID_NDK="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" _DEFAULT_ANDROID_BUILD=x86 _DEFAULT_GAME_NAME=DDNet _DEFAULT_BUILD_TYPE=Debug +_DEFAULT_BUILD_FOLDER=build-android _ANDROID_API_LEVEL=android-24 _ANDROID_SUB_BUILD_DIR=build_arch @@ -38,6 +39,13 @@ else _DEFAULT_BUILD_TYPE=$3 fi +if [ -z ${4+x} ]; then + printf "\e[31m%s\e[30m\n" "Did not pass build folder, using default: ${_DEFAULT_BUILD_FOLDER}" + _SHOW_USAGE_INFO=1 +else + _DEFAULT_BUILD_FOLDER=$4 +fi + _ANDROID_JAR_KEY_NAME=~/.android/debug.keystore _ANDROID_JAR_KEY_PW=android _ANDROID_JAR_KEY_ALIAS=androiddebugkey @@ -99,7 +107,7 @@ function build_for_type() { -DANDROID_NDK="$ANDROID_NDK" \ -DANDROID_ABI="${2}" \ -DANDROID_ARM_NEON=TRUE \ - -Bbuild_android/"$_ANDROID_SUB_BUILD_DIR/$1" \ + -B${_DEFAULT_BUILD_FOLDER}/"$_ANDROID_SUB_BUILD_DIR/$1" \ -DSERVER=OFF \ -DTOOLS=OFF \ -DDEV=TRUE \ @@ -107,12 +115,12 @@ function build_for_type() { -DVULKAN=ON \ -DVIDEORECORDER=OFF ( - cd "build_android/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1 + cd "${_DEFAULT_BUILD_FOLDER}/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1 cmake --build . --target DDNet ) } -mkdir build_android +mkdir ${_DEFAULT_BUILD_FOLDER} if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then build_for_type arm armeabi-v7a arm eabi & @@ -134,7 +142,7 @@ wait printf "\e[36mPreparing gradle build\n" -cd build_android || exit 1 +cd ${_DEFAULT_BUILD_FOLDER} || exit 1 mkdir -p src/main mkdir -p src/main/res/mipmap From ceb1640320291320d7ec0a70b043681859bdfdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 13:22:59 +0200 Subject: [PATCH 07/13] Fix incorrect CMake target name in `cmake_android.sh` The name of the main target was changed from `DDNet` to `game-client`. --- scripts/android/cmake_android.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index 6897a414c..d04851196 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -116,7 +116,7 @@ function build_for_type() { -DVIDEORECORDER=OFF ( cd "${_DEFAULT_BUILD_FOLDER}/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1 - cmake --build . --target DDNet + cmake --build . --target game-client ) } From b2c2a74db73b2f9ba99ff853af0bc497e12bb25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 14:09:20 +0200 Subject: [PATCH 08/13] Remove unused shell script function arguments Only the first two arguments of the `build_for_type` and `copy_libs` functions are used. --- scripts/android/cmake_android.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index d04851196..8035f82bc 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -123,19 +123,19 @@ function build_for_type() { mkdir ${_DEFAULT_BUILD_FOLDER} if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type arm armeabi-v7a arm eabi & + build_for_type arm armeabi-v7a & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type arm64 arm64-v8a aarch64 & + build_for_type arm64 arm64-v8a & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type x86 x86 i686 & + build_for_type x86 x86 & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86_64" || "${_DEFAULT_ANDROID_BUILD}" == "x64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type x86_64 x86_64 x86_64 & + build_for_type x86_64 x86_64 & fi wait @@ -177,19 +177,19 @@ function copy_libs() { } if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - copy_libs arm armeabi-v7a arm eabi + copy_libs arm armeabi-v7a fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - copy_libs arm64 arm64-v8a aarch64 + copy_libs arm64 arm64-v8a fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - copy_libs x86 x86 i686 + copy_libs x86 x86 fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86_64" || "${_DEFAULT_ANDROID_BUILD}" == "x64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - copy_libs x86_64 x86_64 x86_64 + copy_libs x86_64 x86_64 fi _DEFAULT_ANDROID_BUILD_DUMMY=$_DEFAULT_ANDROID_BUILD From cdbe1f775a7b2a19ff33fb5c0882ae29a684f604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 16:34:49 +0200 Subject: [PATCH 09/13] Various fixes/improvements to Android building scripts Use [cargo-ndk](https://github.com/bbqsrc/cargo-ndk) to configure cargo for building with the Android NDK. The output of `cargo ndk` is written to a subfolder for the target triplet, which cannot be changed by parameter. Therefore, the `CARGO_BUILD_DIR` is changed to this subfolder for the Android build, so the build process can find the output. Use `$HOME` instead of `~` because cargo-ndk cannot correctly access the folder otherwise (will fail with error message indicating it could not determine the NDK version). Add `DDNET_TEST_NO_LINK=ON` CMake argument, to fix Rust linking errors with tests. Add additional CMake arguments to specify system name, API version and NDK location. Upgrade to Android API 34. Use `nproc` instead of `32` threads for building. --- CMakeLists.txt | 12 +++++-- scripts/android/cmake_android.sh | 39 +++++++++++++++-------- scripts/compile_libs/cmake_lib_compile.sh | 16 +++++++--- scripts/compile_libs/gen_libs.sh | 4 +-- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad42e0ee7..73756f23d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -866,9 +866,15 @@ set_glob(RUST_MASTERSRV GLOB "rs;toml" src/mastersrv/src add_library(rust-bridge-shared EXCLUDE_FROM_ALL OBJECT ${RUST_BRIDGE_SHARED}) list(APPEND TARGETS_OWN rust-bridge-shared) -set(CARGO_BUILD_DIR "") -set(CARGO_BUILD ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} DDNET_TEST_NO_LINK=1 ${RUST_CARGO} build) -set(CARGO_TEST ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} ${RUST_CARGO} test) +if(TARGET_OS STREQUAL "android") + set(CARGO_BUILD_DIR "${CARGO_NDK_TARGET}/") + set(CARGO_BUILD ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} DDNET_TEST_NO_LINK=1 ${RUST_CARGO} ndk -t ${CARGO_NDK_TARGET} -p ${CARGO_NDK_API} build) + set(CARGO_TEST ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} ${RUST_CARGO} ndk -t ${CARGO_NDK_TARGET} -p ${CARGO_NDK_API} test) +else() + set(CARGO_BUILD_DIR "") + set(CARGO_BUILD ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} DDNET_TEST_NO_LINK=1 ${RUST_CARGO} build) + set(CARGO_TEST ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${PROJECT_BINARY_DIR} ${RUST_CARGO} test) +endif() if(MSVC) list(INSERT CARGO_BUILD 0 ${CMAKE_COMMAND} -E env $<$:CFLAGS=/MTd> $<$:CXXFLAGS=/MTd>) list(INSERT CARGO_TEST 0 ${CMAKE_COMMAND} -E env RUSTFLAGS=-Ctarget-feature=+crt-static) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index 8035f82bc..cadfd88a6 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -1,18 +1,22 @@ #!/bin/bash -export ANDROID_HOME=~/Android/Sdk -export MAKEFLAGS=-j32 +# $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_VERSION must be exported for build.sh step export ANDROID_NDK_VERSION -ANDROID_NDK="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" +# ANDROID_NDK_HOME must be exported for cargo-ndk +export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" _DEFAULT_ANDROID_BUILD=x86 _DEFAULT_GAME_NAME=DDNet _DEFAULT_BUILD_TYPE=Debug _DEFAULT_BUILD_FOLDER=build-android -_ANDROID_API_LEVEL=android-24 +_ANDROID_API_LEVEL=34 _ANDROID_SUB_BUILD_DIR=build_arch @@ -102,12 +106,19 @@ function build_for_type() { -G "Ninja" \ -DPREFER_BUNDLED_LIBS=ON \ -DCMAKE_BUILD_TYPE="${_DEFAULT_BUILD_TYPE}" \ - -DANDROID_NATIVE_API_LEVEL="$_ANDROID_API_LEVEL" \ - -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ - -DANDROID_NDK="$ANDROID_NDK" \ + -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 \ - -B${_DEFAULT_BUILD_FOLDER}/"$_ANDROID_SUB_BUILD_DIR/$1" \ + -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" \ + -DDDNET_TEST_NO_LINK=ON \ + -B"${_DEFAULT_BUILD_FOLDER}/$_ANDROID_SUB_BUILD_DIR/$1" \ -DSERVER=OFF \ -DTOOLS=OFF \ -DDEV=TRUE \ @@ -120,29 +131,29 @@ function build_for_type() { ) } -mkdir ${_DEFAULT_BUILD_FOLDER} +mkdir "${_DEFAULT_BUILD_FOLDER}" if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type arm armeabi-v7a & + build_for_type arm armeabi-v7a armv7-linux-androideabi & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "arm64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type arm64 arm64-v8a & + build_for_type arm64 arm64-v8a aarch64-linux-android & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type x86 x86 & + build_for_type x86 x86 i686-linux-android & fi if [[ "${_DEFAULT_ANDROID_BUILD}" == "x86_64" || "${_DEFAULT_ANDROID_BUILD}" == "x64" || "${_DEFAULT_ANDROID_BUILD}" == "all" ]]; then - build_for_type x86_64 x86_64 & + build_for_type x86_64 x86_64 x86_64-linux-android & fi wait printf "\e[36mPreparing gradle build\n" -cd ${_DEFAULT_BUILD_FOLDER} || exit 1 +cd "${_DEFAULT_BUILD_FOLDER}" || exit 1 mkdir -p src/main mkdir -p src/main/res/mipmap diff --git a/scripts/compile_libs/cmake_lib_compile.sh b/scripts/compile_libs/cmake_lib_compile.sh index ba11a4a19..4109e115b 100755 --- a/scripts/compile_libs/cmake_lib_compile.sh +++ b/scripts/compile_libs/cmake_lib_compile.sh @@ -1,10 +1,11 @@ #!/bin/bash ANDROID_HOME=~/Android/Sdk -ANDROID_NDK="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" -echo "$ANDROID_NDK" +ANDROID_NDK_HOME="$(find "$ANDROID_HOME/ndk" -maxdepth 1 | sort -n | tail -1)" +export ANDROID_NDK_HOME -export MAKEFLAGS=-j32 +MAKEFLAGS=-j$(nproc) +export MAKEFLAGS if [[ "${2}" == "webasm" ]]; then COMPILEFLAGS="-pthread -O3 -g -s USE_PTHREADS=1" @@ -20,10 +21,15 @@ function compile_source() { -H. \ -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=Release \ - -DANDROID_NATIVE_API_LEVEL="android-$1" \ - -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ + -DANDROID_PLATFORM="android-$1" \ + -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \ + -DANDROID_NDK="$ANDROID_NDK_HOME" \ -DANDROID_ABI="${3}" \ -DANDROID_ARM_NEON=TRUE \ + -DCMAKE_ANDROID_NDK="$ANDROID_NDK_HOME" \ + -DCMAKE_SYSTEM_NAME=Android \ + -DCMAKE_SYSTEM_VERSION="$1" \ + -DCMAKE_ANDROID_ARCH_ABI="${3}" \ -B"$2" \ -DBUILD_SHARED_LIBS=OFF \ -DHIDAPI_SKIP_LIBUSB=TRUE \ diff --git a/scripts/compile_libs/gen_libs.sh b/scripts/compile_libs/gen_libs.sh index 7d144585a..00e0521c8 100755 --- a/scripts/compile_libs/gen_libs.sh +++ b/scripts/compile_libs/gen_libs.sh @@ -53,6 +53,8 @@ fi mkdir -p "$1" cd "$1" || exit 1 +_ANDROID_ABI_LEVEL=34 + function build_cmake_lib() { if [ ! -d "${1}" ]; then if [ -z ${3+x} ]; then @@ -68,8 +70,6 @@ function build_cmake_lib() { ) } -_ANDROID_ABI_LEVEL=24 - mkdir -p compile_libs cd compile_libs || exit 1 From 664b0e98bb88938eda5571e05066dac087fe2b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 8 May 2024 12:44:53 +0200 Subject: [PATCH 10/13] Upgrade Gradle and fix Android deprecation errors Upgrade to Gradle 8.5 and Gradle Plugin 8.3.0 for compatibility with Java 21. Explicity set Java version 21 in `build.gradle`. Increment compile and target SDK version to 34 accordingly. Remove the explicitly defined, obsolete `buildToolsVersion` property in `build.gradle`, as it is now automatically derived by Gradle. Replace the deprecated property `android:extractNativeLibs` in `AndroidMainfest.xml` with `useLegacyPackaging` in `build.gradle`. Replace the deprecated package definition `package="tw.DDNet"` in `AndroidMainfest.xml` with `namespace("tw.DDNet")` in `build.gradle`. Add the required property `android:exported="true"` to the main activity in `AndroidMainfest.xml`. --- scripts/android/files/AndroidManifest.xml | 10 ++++------ scripts/android/files/build.gradle | 20 ++++++++++++++----- .../android/files/gradle-wrapper.properties | 2 +- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/scripts/android/files/AndroidManifest.xml b/scripts/android/files/AndroidManifest.xml index f63c07fa6..5c57de0f4 100644 --- a/scripts/android/files/AndroidManifest.xml +++ b/scripts/android/files/AndroidManifest.xml @@ -1,6 +1,5 @@ - + - - - diff --git a/scripts/android/files/build.gradle b/scripts/android/files/build.gradle index 417e1b23d..403dc50d1 100644 --- a/scripts/android/files/build.gradle +++ b/scripts/android/files/build.gradle @@ -10,19 +10,25 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:8.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" + compileSdkVersion 34 ndkVersion "TW_NDK_VERSION" defaultConfig { applicationId "tw.DDNet" + namespace("tw.DDNet") minSdkVersion 24 - targetSdkVersion 30 + targetSdkVersion 34 versionCode TW_VERSION_CODE versionName "TW_VERSION_NAME" } @@ -46,7 +52,11 @@ android { shrinkResources false } } - + packagingOptions { + jniLibs { + useLegacyPackaging = true + } + } sourceSets { main { assets.srcDirs = ['assets'] diff --git a/scripts/android/files/gradle-wrapper.properties b/scripts/android/files/gradle-wrapper.properties index aa991fcea..a59520664 100644 --- a/scripts/android/files/gradle-wrapper.properties +++ b/scripts/android/files/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 51e4e41805fbd8d539f8814a1686b5e00dc8e0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Thu, 9 May 2024 11:52:37 +0200 Subject: [PATCH 11/13] Change `tw.DDNet` package name to `org.ddnet.client` --- scripts/android/cmake_android.sh | 25 +++++++----- scripts/android/files/AndroidManifest.xml | 2 +- scripts/android/files/build.gradle | 4 +- scripts/android/files/build.sh | 40 ++++++++++--------- .../ddnet/client}/NativeMain.java | 5 ++- scripts/android/files/proguard-rules.pro | 2 +- 6 files changed, 43 insertions(+), 35 deletions(-) rename scripts/android/files/java/{tw/DDNet => org/ddnet/client}/NativeMain.java (90%) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index cadfd88a6..d7aeca8b6 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -14,6 +14,7 @@ export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$ANDROID_NDK_VERSION" _DEFAULT_ANDROID_BUILD=x86 _DEFAULT_GAME_NAME=DDNet +_DEFAULT_PACKAGE_NAME=org.ddnet.client _DEFAULT_BUILD_TYPE=Debug _DEFAULT_BUILD_FOLDER=build-android _ANDROID_API_LEVEL=34 @@ -37,17 +38,24 @@ else fi if [ -z ${3+x} ]; then - printf "\e[31m%s\e[30m\n" "Did not pass build type, using default: ${_DEFAULT_BUILD_TYPE}" + printf "\e[31m%s\e[30m\n" "Did not pass package name, using default: ${_DEFAULT_PACKAGE_NAME}" _SHOW_USAGE_INFO=1 else - _DEFAULT_BUILD_TYPE=$3 + _DEFAULT_PACKAGE_NAME=$3 fi if [ -z ${4+x} ]; then + printf "\e[31m%s\e[30m\n" "Did not pass build type, using default: ${_DEFAULT_BUILD_TYPE}" + _SHOW_USAGE_INFO=1 +else + _DEFAULT_BUILD_TYPE=$4 +fi + +if [ -z ${5+x} ]; then printf "\e[31m%s\e[30m\n" "Did not pass build folder, using default: ${_DEFAULT_BUILD_FOLDER}" _SHOW_USAGE_INFO=1 else - _DEFAULT_BUILD_FOLDER=$4 + _DEFAULT_BUILD_FOLDER=$5 fi _ANDROID_JAR_KEY_NAME=~/.android/debug.keystore @@ -92,10 +100,10 @@ fi export TW_VERSION_NAME=$_ANDROID_VERSION_NAME -printf "\e[31m%s\e[1m\n" "Building with setting, for arch: ${_DEFAULT_ANDROID_BUILD}, with build type: ${_DEFAULT_BUILD_TYPE}, with name: ${_DEFAULT_GAME_NAME}" +printf "\e[31m%s\e[1m\n" "Building with setting, for arch: ${_DEFAULT_ANDROID_BUILD}, with build type: ${_DEFAULT_BUILD_TYPE}, with name: ${_DEFAULT_GAME_NAME} (${_DEFAULT_PACKAGE_NAME})" if [ $_SHOW_USAGE_INFO == 1 ]; then - printf "\e[31m%s\e[1m\n" "Usage: ./cmake_android.sh " + printf "\e[31m%s\e[1m\n" "Usage: ./cmake_android.sh " fi printf "\e[33mBuilding cmake\e[0m\n" @@ -238,15 +246,12 @@ printf "\e[0m" echo "Building..." -rm -R src/main/java/tw -mkdir -p src/main/java/tw/DDNet -cp ../scripts/android/files/java/tw/DDNet/NativeMain.java src/main/java/tw/DDNet/NativeMain.java - rm -R 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 "$ANDROID_HOME" "$_DEFAULT_GAME_NAME" "$_DEFAULT_BUILD_TYPE" +source ./build.sh "$_DEFAULT_GAME_NAME" "$_DEFAULT_PACKAGE_NAME" "$_DEFAULT_BUILD_TYPE" cd .. diff --git a/scripts/android/files/AndroidManifest.xml b/scripts/android/files/AndroidManifest.xml index 5c57de0f4..8f7e705b8 100644 --- a/scripts/android/files/AndroidManifest.xml +++ b/scripts/android/files/AndroidManifest.xml @@ -26,7 +26,7 @@ android:roundIcon="@mipmap/ic_launcher_round" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"> diff --git a/scripts/android/files/build.gradle b/scripts/android/files/build.gradle index 403dc50d1..e9df90729 100644 --- a/scripts/android/files/build.gradle +++ b/scripts/android/files/build.gradle @@ -25,8 +25,8 @@ android { compileSdkVersion 34 ndkVersion "TW_NDK_VERSION" defaultConfig { - applicationId "tw.DDNet" - namespace("tw.DDNet") + applicationId "org.ddnet.client" + namespace("org.ddnet.client") minSdkVersion 24 targetSdkVersion 34 versionCode TW_VERSION_CODE diff --git a/scripts/android/files/build.sh b/scripts/android/files/build.sh index d61843695..df9a6c208 100644 --- a/scripts/android/files/build.sh +++ b/scripts/android/files/build.sh @@ -1,12 +1,12 @@ #!/bin/bash [ "$1" == "" ] && { - printf '\e[31mDid not pass ANDROID_SDK_ROOT to build script\e[30m\n' + printf '\e[31mDid not pass APK name to build script\e[30m\n' exit 1 } [ "$2" == "" ] && { - printf '\e[31mDid not pass APK name to build script\e[30m\n' + printf '\e[31mDid not pass package name to build script\e[30m\n' exit 1 } @@ -15,13 +15,15 @@ exit 1 } -_APK_BASENAME="$2" +_APK_BASENAME="$1" +_APK_PACKAGE_NAME="$2" +_APK_BUILD_TYPE="$3" -sed -i "s/DDNet/${2}/g" settings.gradle +_APK_PACKAGE_FOLDER=$(echo "$_APK_PACKAGE_NAME"|sed 's/\./\//g') -_REPLACE_PACKAGE_NAME_STR="tw.${2,,}" +sed -i "s/DDNet/${_APK_BASENAME}/g" settings.gradle -sed -i "s/tw.DDNet/${_REPLACE_PACKAGE_NAME_STR}/g" build.gradle +sed -i "s/org.ddnet.client/${_APK_PACKAGE_NAME}/g" build.gradle TW_KEY_NAME_ESCAPED=$(echo "$TW_KEY_NAME"|sed 's/\//\\\//g') TW_KEY_PW_ESCAPED=$(echo "$TW_KEY_PW"|sed 's/\//\\\//g') @@ -31,35 +33,35 @@ sed -i "s/TW_KEY_NAME/${TW_KEY_NAME_ESCAPED}/g" build.gradle sed -i "s/TW_KEY_PW/${TW_KEY_PW_ESCAPED}/g" build.gradle sed -i "s/TW_KEY_ALIAS/${TW_KEY_ALIAS_ESCAPED}/g" build.gradle -sed -i "s/DDNet/${2}/g" src/main/res/values/strings.xml - -sed -i "s/\"DDNet\"/\"${2}\"/g" src/main/AndroidManifest.xml -sed -i "s/tw.DDNet/${_REPLACE_PACKAGE_NAME_STR}/g" src/main/AndroidManifest.xml - sed -i "s/TW_NDK_VERSION/${ANDROID_NDK_VERSION}/g" build.gradle sed -i "s/TW_VERSION_CODE/${TW_VERSION_CODE}/g" build.gradle sed -i "s/TW_VERSION_NAME/${TW_VERSION_NAME}/g" build.gradle -mv src/main/java/tw/DDNet src/main/java/tw/"${2}" +sed -i "s/DDNet/${_APK_BASENAME}/g" src/main/res/values/strings.xml -sed -i "s/tw.DDNet/${_REPLACE_PACKAGE_NAME_STR}/g" src/main/java/tw/"${2}"/NativeMain.java -sed -i "s/tw.DDNet/${_REPLACE_PACKAGE_NAME_STR}/g" proguard-rules.pro +sed -i "s/\"DDNet\"/\"${_APK_BASENAME}\"/g" src/main/AndroidManifest.xml +sed -i "s/org.ddnet.client/${_APK_PACKAGE_NAME}/g" src/main/AndroidManifest.xml + +mv src/main/java/org/ddnet/client src/main/java/"${_APK_PACKAGE_FOLDER}" + +sed -i "s/org.ddnet.client/${_APK_PACKAGE_NAME}/g" src/main/java/"${_APK_PACKAGE_FOLDER}"/NativeMain.java +sed -i "s/org.ddnet.client/${_APK_PACKAGE_NAME}/g" proguard-rules.pro # disable hid manager for now sed -i "s/mHIDDeviceManager = HIDDeviceManager.acquire(this);/mHIDDeviceManager=null;/g" src/main/java/org/libsdl/app/SDLActivity.java -if [[ "${3}" == "Debug" ]]; then +if [[ "${_APK_BUILD_TYPE}" == "Debug" ]]; then sed -i "s/android.enableR8.fullMode=true/android.enableR8.fullMode=false/g" gradle.properties fi if [[ -z ${GE_NO_APK_BUILD} || "${GE_NO_APK_BUILD}" != "1" ]]; then _RELEASE_TYPE_NAME=debug _RELEASE_TYPE_APK_NAME= - if [[ "${3}" == "Debug" ]]; then + if [[ "${_APK_BUILD_TYPE}" == "Debug" ]]; then _RELEASE_TYPE_NAME=debug fi - if [[ "${3}" == "Release" ]]; then + if [[ "${_APK_BUILD_TYPE}" == "Release" ]]; then _RELEASE_TYPE_NAME=release _RELEASE_TYPE_APK_NAME= fi @@ -67,7 +69,7 @@ if [[ -z ${GE_NO_APK_BUILD} || "${GE_NO_APK_BUILD}" != "1" ]]; then APP_BASE_NAME=Gradle CLASSPATH=gradle-wrapper.jar java "-Dorg.gradle.appname=${APP_BASE_NAME}" -classpath "${CLASSPATH}" org.gradle.wrapper.GradleWrapperMain --warning-mode all - if [[ "${3}" == "Debug" ]]; then + if [[ "${_APK_BUILD_TYPE}" == "Debug" ]]; then java "-Dorg.gradle.appname=${APP_BASE_NAME}" -classpath "${CLASSPATH}" org.gradle.wrapper.GradleWrapperMain --warning-mode all builddebug java "-Dorg.gradle.appname=${APP_BASE_NAME}" -classpath "${CLASSPATH}" org.gradle.wrapper.GradleWrapperMain --warning-mode all assembleDebug else @@ -77,7 +79,7 @@ if [[ -z ${GE_NO_APK_BUILD} || "${GE_NO_APK_BUILD}" != "1" ]]; then cp build/outputs/apk/"$_RELEASE_TYPE_NAME"/"$_APK_BASENAME"-"$_RELEASE_TYPE_NAME""$_RELEASE_TYPE_APK_NAME".apk "$_APK_BASENAME".apk - if [[ "${3}" == "Release" ]]; then + if [[ "${_APK_BUILD_TYPE}" == "Release" ]]; then java "-Dorg.gradle.appname=${APP_BASE_NAME}" -classpath "${CLASSPATH}" org.gradle.wrapper.GradleWrapperMain --warning-mode all bundleRelease cp build/outputs/bundle/"$_RELEASE_TYPE_NAME"/"$_APK_BASENAME"-"$_RELEASE_TYPE_NAME""$_RELEASE_TYPE_APK_NAME".aab "$_APK_BASENAME".aab diff --git a/scripts/android/files/java/tw/DDNet/NativeMain.java b/scripts/android/files/java/org/ddnet/client/NativeMain.java similarity index 90% rename from scripts/android/files/java/tw/DDNet/NativeMain.java rename to scripts/android/files/java/org/ddnet/client/NativeMain.java index 4cd429a8c..890fc8c7f 100644 --- a/scripts/android/files/java/tw/DDNet/NativeMain.java +++ b/scripts/android/files/java/org/ddnet/client/NativeMain.java @@ -1,4 +1,5 @@ -package tw.DDNet; +package org.ddnet.client; + import android.app.NativeActivity; import org.libsdl.app.SDLActivity; import android.os.Bundle; @@ -12,7 +13,7 @@ public class NativeMain extends SDLActivity { @Override protected String[] getLibraries() { return new String[] { - // disable hid API for now + // disable hid API for now // "hidapi", // "SDL2", "DDNet", diff --git a/scripts/android/files/proguard-rules.pro b/scripts/android/files/proguard-rules.pro index 7b5bd236a..ebf7b3d1f 100644 --- a/scripts/android/files/proguard-rules.pro +++ b/scripts/android/files/proguard-rules.pro @@ -16,7 +16,7 @@ # debugging stack traces. #-keepattributes SourceFile,LineNumberTable --keepclassmembers, allowoptimization public class tw.DDNet.NativeMain { +-keepclassmembers, allowoptimization public class org.ddnet.client.NativeMain { *; } From e4a7fd59f751fe8ebb5d40f75b4f12bae5807744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Thu, 9 May 2024 12:19:47 +0200 Subject: [PATCH 12/13] Determine default version name and code from `version.h` Parse `GAME_RELEASE_VERSION` and `DDNET_VERSION_NUMBER` definitions from `src/game/version.h` by default, so specifying a version manually is usually not necessary. --- scripts/android/cmake_android.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/android/cmake_android.sh b/scripts/android/cmake_android.sh index d7aeca8b6..116adba2d 100755 --- a/scripts/android/cmake_android.sh +++ b/scripts/android/cmake_android.sh @@ -84,7 +84,11 @@ export TW_KEY_ALIAS=$_ANDROID_JAR_KEY_ALIAS _ANDROID_VERSION_CODE=1 if [ -z ${TW_VERSION_CODE+x} ]; then - printf "\e[31m%s\e[30m\n" "Did not pass a version code, using default: ${_ANDROID_VERSION_CODE}" + _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 "\e[31m%s\e[30m\n" "Did not pass a version code, using default: ${_ANDROID_VERSION_CODE}" else _ANDROID_VERSION_CODE=$TW_VERSION_CODE fi @@ -93,7 +97,11 @@ export TW_VERSION_CODE=$_ANDROID_VERSION_CODE _ANDROID_VERSION_NAME="1.0" if [ -z ${TW_VERSION_NAME+x} ]; then - printf "\e[31m%s\e[30m\n" "Did not pass a version name, using default: ${_ANDROID_VERSION_NAME}" + _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 "\e[31m%s\e[30m\n" "Did not pass a version name, using default: ${_ANDROID_VERSION_NAME}" else _ANDROID_VERSION_NAME=$TW_VERSION_NAME fi From 1316ac3c7026e3b6b5b498b6a4e22a0da583f948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Tue, 7 May 2024 11:50:47 +0200 Subject: [PATCH 13/13] Improve the Android building `README.md` --- scripts/android/README.md | 180 ++++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 44 deletions(-) diff --git a/scripts/android/README.md b/scripts/android/README.md index cb95ebba8..561aaea13 100644 --- a/scripts/android/README.md +++ b/scripts/android/README.md @@ -1,53 +1,145 @@ -Requirements for building: -========================== -- Android NDK (tested with NDK 23), must be in the same location in which Android studio would unpack it (~/Android/Sdk/ndk/) - at least version 23 -- Android SDK build tools - version 30.0.3 -- ddnet-libs with Android libs -- Java -- JDK 11+ -- 7zip (for ddnet-libs building) -- ninja -- curl runtime +Requirements for building for Android +===================================== -How to build: -============= -- run a terminal inside the source directory: - `scripts/android/cmake_android.sh ` - where the first parameter is the arch (all for all arches), the second is the apk name, which must be equal to the library name (if you want to rename the APK do it after the build) - and the third parameter which simply defines the build type - -- if you build with a signing key for the APK - Generate one with - `keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias` - export environment variables for the script +- At least 10-15 GiB of free disk space. +- First follow the general instructions for setting up https://github.com/ddnet/ddnet for building on Linux. + This guide has only been tested on Linux. +- Install the Android NDK (version 26) in the same location + where Android Studio would unpack it (`~/Android/Sdk/ndk/`): + ```shell + mkdir ~/Android + cd ~/Android + mkdir Sdk + cd Sdk + mkdir ndk + cd ndk + wget https://dl.google.com/android/repository/android-ndk-r26d-linux.zip + unzip android-ndk-r26d-linux.zip + unlink android-ndk-r26d-linux.zip ``` +- Install the Android SDK build tools (version 30.0.3) in the same location + where Android Studio would unpack them (`~/Android/Sdk/build-tools/`): + ```shell + # Assuming you already created the Android/Sdk folders in the previous step + cd ~/Android/Sdk + mkdir build-tools + cd build-tools + wget https://dl.google.com/android/repository/build-tools_r30.0.3-linux.zip + unzip build-tools_r30.0.3-linux.zip + unlink build-tools_r30.0.3-linux.zip + mv android-11 30.0.3 + ``` +- Install the Android command-line tools and accept the licenses using the SDK manager, + otherwise the Gradle build will fail if the licenses have not been accepted: + ```shell + # Assuming you already created the Android/Sdk folders in the previous step + cd ~/Android/Sdk + mkdir cmdline-tools + cd cmdline-tools + wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip + unzip commandlinetools-linux-11076708_latest.zip + unlink commandlinetools-linux-11076708_latest.zip + mv cmdline-tools latest + yes | latest/bin/sdkmanager --licenses + ``` +- Install cargo-ndk and add Android targets to rustup to build Rust with the Android NDK: + ```shell + cargo install cargo-ndk + rustup target add armv7-linux-androideabi + rustup target add i686-linux-android + rustup target add aarch64-linux-android + rustup target add x86_64-linux-android + ``` +- Install OpenJDK 21: + ```shell + sudo apt install openjdk-21-jdk + ``` +- Install 7zip for building `ddnet-libs`: + ```shell + sudo apt install p7zip-full + ``` +- Install ninja: + ```shell + sudo apt install ninja-build + ``` +- Install curl: + ```shell + sudo apt install curl + ``` +- *(macOS only)* Install coreutils so `nproc` is available: + ```shell + brew install coreutils + ``` +- Build the `ddnet-libs` for Android (see below). Follow all above steps first. + + +How to build the `ddnet-libs` for Android +========================================= + +- There is a script to automatically download and build all repositories, + this requires an active internet connection and can take around 30 minutes: + ```shell + mkdir build-android-libs + scripts/compile_libs/gen_libs.sh build-android-libs android + ``` + **Warning**: Do not choose a directory inside the `src` folder! +- If you see several red error messages in the first few minutes, + abort the compilation with repeated Ctrl+C presses. + Examine the output and ensure that you installed the NDK to the correct location. +- After the script finished executing, it should have created a `ddnet-libs` directory + in your selected output folder, which contains all libraries in the correct directory + format and can be merged with the `ddnet-libs` folder in the source directory: + ```shell + cp -r build-android-libs/ddnet-libs/. ddnet-libs/ + ``` + + +How to build the DDNet client for Android +========================================= + +- Open a terminal inside the `ddnet` project root directory and run the following: + ```shell + scripts/android/cmake_android.sh + ``` + - The first parameter denotes the architecture. + Use `all` to compile for all architectures. + Note that all architectures will be compiled in parallel. + For testing, only compile for one architecture initially to get readable output. + - The second parameter denotes the APK name, which must be equal to the library name. + If you want to rename the APK, do it after the build. + - The third parameter denotes the package name of the APK. + - The fourth parameter denotes the build type. + - The fifth parameter denotes the build folder. +- Example to build only for `x86_64` architecture in debug mode: + ```shell + scripts/android/cmake_android.sh x86_64 DDNet org.ddnet.client Debug build-android-debug + ``` +- To build a signed APK, generate a signing key and export environment variables before running the build script: + ```shell + keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias export TW_KEY_NAME= export TW_KEY_PW= export TW_KEY_ALIAS= ``` - so for example: - ``` - keytool -genkey -v -keystore Teeworlds.jks -keyalg RSA -keysize 2048 -validity 10000 -alias Teeworlds-Key - (it will prompt an input:) - Input keystore-password: mypassword - - export TW_KEY_NAME=Teeworlds.jks - export TW_KEY_PW=mypassword - export TW_KEY_ALIAS=Teeworlds-Key - scripts/android/cmake_android.sh all DDNet Release - ``` - - You can also specify the build version code and build version string before running the build script, e.g.: - ``` +- By default, the version code and name of the APK will be determined automatically + based on the definitions in `src/game/version.h`. + You can also specify the build version code and name manually before running the build script, e.g.: + ```shell export TW_VERSION_CODE=20210819 export TW_VERSION_NAME="1.0" ``` - -How to build the ddnet-libs for Android: -======================================== -- There is a script to automatically download and build all repositories, this requires an active internet connection: - `scripts/compile_libs/gen_libs.sh android` - Warning!: DO NOT CHOOSE A DIRECTORY INSIDE THE SOURCE TREE - - After the script finished executing it should have created a ddnet-libs directory which created all libs in the right directory format and can be merged with ddnet-libs in the source directory + The version code must increase for newer version in order for users to automatically update to them. + The version name is the string that will be displayed to the user, e.g. `1.2.3-snapshot4`. +- Example to build a signed APK in release mode for all architectures: + ```shell + keytool -genkey -v -keystore Teeworlds.jks -keyalg RSA -keysize 2048 -validity 10000 -alias Teeworlds-Key + # It will prompt for the password, input for example "mypassword" + export TW_KEY_NAME=Teeworlds.jks + export TW_KEY_PW=mypassword + export TW_KEY_ALIAS=Teeworlds-Key + # Version code and name will be determined automatically + scripts/android/cmake_android.sh all DDNet org.ddnet.client Release build-android-release + ``` +- Note that you should only generate a signing key once (and make backups). + Users can only update apps automatically if the same package name and signing key have been used, + else they must manually uninstall the old app.