Skip to content

Commit

Permalink
Support building Android version on Windows with MSYS2
Browse files Browse the repository at this point in the history
Support user-defined `ANDROID_HOME` variable in the `cmake_android.sh` script to specify different location for the Android SDK installation. See https://developer.android.com/tools/variables#envar for details.

Make generation of data integrity index file in the `cmake_android.sh` script faster by factor >100 in MSYS2 by avoiding the loop over piped output.

Locally prepend `/usr/bin/` to the `PATH` variable in the `cmake_android.sh` script to ensure that the MSYS2 binaries are used instead of Windows-native tools with the same names which work differently like `find` and `sort`.

Update ddnet-libs reference to include the Android libs (latest ddnet-libs master) which cannot currently be build on Windows.

Update README with steps for building the Android version on Windows with MSYS2.
  • Loading branch information
Robyt3 committed Dec 4, 2024
1 parent c6e7e27 commit 1cb72e5
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 20 deletions.
2 changes: 1 addition & 1 deletion ddnet-libs
Submodule ddnet-libs updated 530 files
66 changes: 58 additions & 8 deletions scripts/android/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Requirements for building for Android
=====================================
Requirements for building for Android on Linux
==============================================

- 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.
- Note: Use a stable version of Rust. Using the nightly version results in linking errors.
- Install the Android NDK (version 26) in the same location
where Android Studio would unpack it (`~/Android/Sdk/ndk/`):
Expand Down Expand Up @@ -55,10 +54,6 @@ Requirements for building for Android
```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
Expand All @@ -72,11 +67,57 @@ Requirements for building for Android
brew install coreutils
```
- Build the `ddnet-libs` for Android (see below). Follow all above steps first.
Alternatively, use the precompiled libraries from https://github.com/ddnet/ddnet-libs/.

Requirements for building for Android on Windows using MSYS2
============================================================

- At least 50 GiB of free disk space if you start from scratch.
- First install MSYS2 (https://www.msys2.org/wiki/MSYS2-installation/) as well as all required packages for building DDNet using MSYS2 on Windows.
(There is currently no more detailed guide for this.)
- 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 JDK 21, e.g. from https://adoptium.net/temurin/releases/?package=jdk&os=windows&version=21
- Install ninja:
```shell
pacman -S mingw-w64-x86_64-ninja
```
- Install curl:
```shell
pacman -S mingw-w64-x86_64-curl
```
- Install coreutils so `nproc` is available:
```shell
pacman -S coreutils
```
- Compiling the libraries is not supported on Windows yet. Use the precompiled libraries from https://github.com/ddnet/ddnet-libs/,
i.e. make sure to also clone the ddnet-libs submodule, or compile the libraries on a separate Linux system.
- Set the `ANDROID_HOME` environment variable to override the location where the Android SDK will be installed, e.g. `C:/Android/SDK`. Make sure to only use forward slashes.
- Install either Android Studio (which includes an SDK manager GUI) from https://developer.android.com/studio or the standalone command-line tools (which include the `sdkmanager` tool) from https://developer.android.com/studio/#command-line-tools-only.
- When using the command-line tools: Ensure the command-line tools are installed at the expected location, so `%ANDROID_HOME%/cmdline-tools/latest/bin` should contain `sdkmanager.bat`.
Accept the licenses using the SDK manager, otherwise the Gradle build will fail if the licenses have not been accepted:
```shell
yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager.bat --licenses
```
- Install the following using the SDK Manager in Android Studio (Tools menu) or the `sdkmanager` command-line tool:
- SDK Platform for API Level 34
- NDK (Side by side)
- Android SDK Build-Tools (latest version)

How to build the `ddnet-libs` for Android
=========================================

- Note: This has only been tested on Linux.
- Install 7-Zip:
```shell
sudo apt install p7zip-full
```
- There is a script to automatically download and build all repositories,
this requires an active internet connection and can take around 30 minutes:
```shell
Expand All @@ -94,10 +135,10 @@ How to build the `ddnet-libs` for Android
cp -r build-android-libs/ddnet-libs/. ddnet-libs/
```


How to build the DDNet client for Android
=========================================

- These steps are identical on Linux and Windows, except on Windows `bash` must be used as terminal and not `cmd.exe` or PowerShell.
- 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>
Expand Down Expand Up @@ -144,3 +185,12 @@ How to build the DDNet client for Android
- 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.

Common problems and solutions
=============================

- If the Gradle build fails with errors messages indicating bugs relating to files in the Gradle cache, try to clear the Gradle cache by deleting the contents of the folder `~/.gradle/caches` (`%USERPROFILE%/.gradle/caches` on Windows).
- The Gradle build may show a message that the JDK version could not be determined but this can safely be ignored.
- The Gradle build will fail with errors messages indicating an unsupported class file version if a different version of the JDK is used than specified in `build.gradle`.
When incrementing the supported JDK version, the Gradle version also has to be incremented according to https://docs.gradle.org/current/userguide/compatibility.html.
If you have multiple JDKs installed, you can set the JDK version for Gradle using the property `org.gradle.java.home` in the `gradle.properties` file in your Gradle home directory.
25 changes: 14 additions & 11 deletions scripts/android/cmake_android.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#!/bin/bash
set -e

# $HOME must be used instead of ~ else cargo-ndk cannot find the folder
export ANDROID_HOME=$HOME/Android/Sdk
# Ensure that binaries from MSYS2 are preferred over Windows-native commands like find and sort which work differently.
PATH="/usr/bin/:$PATH"

# $ANDROID_HOME can be used-defined, else the default location is used. Important notes:
# - The path must not contain spaces on Windows.
# - $HOME must be used instead of ~ else cargo-ndk cannot find the folder.
ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}"
export ANDROID_HOME

BUILD_FLAGS="${BUILD_FLAGS:--j$(nproc)}"
export BUILD_FLAGS

Expand Down Expand Up @@ -123,8 +130,6 @@ fi

export TW_VERSION_NAME=$ANDROID_VERSION_NAME

printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake..."

function build_for_type() {
cmake \
-H. \
Expand Down Expand Up @@ -160,18 +165,22 @@ function build_for_type() {
mkdir -p "${BUILD_FOLDER}"

if [[ "${ANDROID_BUILD}" == "arm" || "${ANDROID_BUILD}" == "all" ]]; then
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake (arm)..."
build_for_type arm armeabi-v7a armv7-linux-androideabi
fi

if [[ "${ANDROID_BUILD}" == "arm64" || "${ANDROID_BUILD}" == "all" ]]; then
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake (arm64)..."
build_for_type arm64 arm64-v8a aarch64-linux-android
fi

if [[ "${ANDROID_BUILD}" == "x86" || "${ANDROID_BUILD}" == "all" ]]; then
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake (x86)..."
build_for_type x86 x86 i686-linux-android
fi

if [[ "${ANDROID_BUILD}" == "x86_64" || "${ANDROID_BUILD}" == "all" ]]; then
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Building cmake (x86_64)..."
build_for_type x86_64 x86_64 x86_64-linux-android
fi

Expand Down Expand Up @@ -241,14 +250,8 @@ cp ./cacert.pem ./assets/asset_integrity_files/data/cacert.pem || exit 1
printf "${COLOR_CYAN}%s${COLOR_RESET}\n" "Creating integrity index file..."
(
cd assets/asset_integrity_files || exit 1

tmpfile="$(mktemp /tmp/hash_strings.XXX)"

find data -iname "*" -type f -print0 | while IFS= read -r -d $'\0' file; do
sha_hash=$(sha256sum "$file" | cut -d' ' -f 1)
echo "$file $sha_hash" >> "$tmpfile"
done

find data -iname "*" -type f -print0 | xargs -0 sha256sum | awk '{gsub(/^\*/, "", $2); print substr($0, index($0, $2)), $1}' > "$tmpfile"
full_hash="$(sha256sum "$tmpfile" | cut -d' ' -f 1)"

rm -f "integrity.txt"
Expand Down

0 comments on commit 1cb72e5

Please sign in to comment.