mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 21:48:19 +00:00
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:
commit
848f4a846b
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ..
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package tw.DDNet;
|
||||
package org.ddnet.client;
|
||||
|
||||
import android.app.NativeActivity;
|
||||
import org.libsdl.app.SDLActivity;
|
||||
import android.os.Bundle;
|
|
@ -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"
|
2
scripts/android/files/proguard-rules.pro
vendored
2
scripts/android/files/proguard-rules.pro
vendored
|
@ -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 {
|
||||
*;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue