Merge pull request #8334 from Robyt3/Android-Building-Fix

Fix the Android build and improve the Android building `README.md`
This commit is contained in:
heinrich5991 2024-05-22 21:19:40 +00:00 committed by GitHub
commit 848f4a846b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 305 additions and 166 deletions

3
.gitignore vendored
View file

@ -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

View file

@ -870,9 +870,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 $<$<CONFIG:Debug>:CFLAGS=/MTd> $<$<CONFIG:Debug>:CXXFLAGS=/MTd>)
list(INSERT CARGO_TEST 0 ${CMAKE_COMMAND} -E env RUSTFLAGS=-Ctarget-feature=+crt-static)

View file

@ -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 <x86/x86_64/arm/arm64/all> <Game name> <Debug/Release>`
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 <x86/x86_64/arm/arm64/all> <Game name> <Package name> <Debug/Release> <Build folder>
```
- 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=<key name>
export TW_KEY_PW=<key password>
export TW_KEY_ALIAS=<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 <directory to build in> 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.

View file

@ -1,17 +1,23 @@
#!/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_PACKAGE_NAME=org.ddnet.client
_DEFAULT_BUILD_TYPE=Debug
_ANDROID_API_LEVEL=android-24
_DEFAULT_BUILD_FOLDER=build-android
_ANDROID_API_LEVEL=34
_ANDROID_SUB_BUILD_DIR=build_arch
@ -32,10 +38,24 @@ else
fi
if [ -z ${3+x} ]; then
printf "\e[31m%s\e[30m\n" "Did not pass package name, using default: ${_DEFAULT_PACKAGE_NAME}"
_SHOW_USAGE_INFO=1
else
_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=$3
_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=$5
fi
_ANDROID_JAR_KEY_NAME=~/.android/debug.keystore
@ -64,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
@ -73,17 +97,21 @@ 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
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 <x86/x86_64/arm/arm64/all> <Game name> <Debug/Release>"
printf "\e[31m%s\e[1m\n" "Usage: ./cmake_android.sh <x86/x86_64/arm/arm64/all> <Game name> <Package name> <Debug/Release> <Build folder>"
fi
printf "\e[33mBuilding cmake\e[0m\n"
@ -94,12 +122,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 \
-Bbuild_android/"$_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 \
@ -107,34 +142,34 @@ function build_for_type() {
-DVULKAN=ON \
-DVIDEORECORDER=OFF
(
cd "build_android/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1
cmake --build . --target DDNet
cd "${_DEFAULT_BUILD_FOLDER}/$_ANDROID_SUB_BUILD_DIR/$1" || exit 1
cmake --build . --target game-client
)
}
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 &
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 aarch64 &
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 i686 &
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 x86_64 &
build_for_type x86_64 x86_64 x86_64-linux-android &
fi
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
@ -154,7 +189,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
@ -170,19 +204,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
@ -220,15 +254,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 ..

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="tw.DDNet">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature
android:glEsVersion="0x00030000" />
<uses-feature
@ -21,24 +20,23 @@
android:usesCleartextTraffic="true"
android:label="@string/app_name"
android:hasCode="true"
android:extractNativeLibs="true"
android:supportsRtl="true"
android:isGame="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<activity
android:name=".NativeMain"
android:name="org.ddnet.client.NativeMain"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.lib_name"
<meta-data
android:name="android.app.lib_name"
android:value="DDNet" />
</activity>
</application>
</manifest>

View file

@ -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"
applicationId "org.ddnet.client"
namespace("org.ddnet.client")
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']

View file

@ -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,38 +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
__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
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
@ -70,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
@ -80,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

View file

@ -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

View file

@ -1,4 +1,5 @@
package tw.DDNet;
package org.ddnet.client;
import android.app.NativeActivity;
import org.libsdl.app.SDLActivity;
import android.os.Bundle;

View file

@ -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"

View file

@ -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 {
*;
}

View file

@ -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 \

View file

@ -53,9 +53,15 @@ fi
mkdir -p "$1"
cd "$1" || exit 1
_ANDROID_ABI_LEVEL=34
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
@ -64,8 +70,6 @@ function build_cmake_lib() {
)
}
_ANDROID_ABI_LEVEL=24
mkdir -p compile_libs
cd compile_libs || 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

View file

@ -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<std::string> 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,17 +82,18 @@ 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);
GotSHA = true;
}
io_close(IntegritySaveFileRead);
}
}
@ -138,20 +139,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);
}
}
}

View file

@ -4279,16 +4279,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
@ -4302,6 +4292,14 @@ int main(int argc, const char **argv)
#if defined(CONF_PLATFORM_ANDROID)
pStdoutLogger = std::shared_ptr<ILogger>(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<ILogger>(log_logger_stdout());